Merge remote-tracking branch 'origin/master' into develop

v1.18.x
Peter Jaszkowiak 7 years ago
commit 62ae171432

1
.gitignore vendored

@ -58,6 +58,7 @@ tx.exe
##Coverage output ##Coverage output
coverage coverage
.nyc_output
build build
*.log *.log

@ -34,7 +34,7 @@ function getDatabaseConfig(config, callback) {
prompt.get(questions.redis, callback); prompt.get(questions.redis, callback);
} }
} else if (config.database === 'mongo') { } else if (config.database === 'mongo') {
if (config['mongo:host'] && config['mongo:port']) { if ((config['mongo:host'] && config['mongo:port']) || config['mongo:uri']) {
callback(null, config); callback(null, config);
} else { } else {
prompt.get(questions.mongo, callback); prompt.get(questions.mongo, callback);
@ -68,6 +68,7 @@ function saveDatabaseConfig(config, databaseConfig, callback) {
username: databaseConfig['mongo:username'], username: databaseConfig['mongo:username'],
password: databaseConfig['mongo:password'], password: databaseConfig['mongo:password'],
database: databaseConfig['mongo:database'], database: databaseConfig['mongo:database'],
uri: databaseConfig['mongo:uri'],
}; };
} else { } else {
return callback(new Error('unknown database : ' + config.database)); return callback(new Error('unknown database : ' + config.database));

@ -13,38 +13,38 @@
"start": "node loader.js", "start": "node loader.js",
"lint": "eslint --cache ./nodebb .", "lint": "eslint --cache ./nodebb .",
"pretest": "npm run lint", "pretest": "npm run lint",
"test": "istanbul cover node_modules/mocha/bin/_mocha -- -R dot", "test": "nyc --reporter=html --reporter=text-summary mocha",
"coveralls": "istanbul cover _mocha --report lcovonly -- -R dot && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" "coveralls": "nyc report --reporter=text-lcov | coveralls && rm -r coverage"
}, },
"dependencies": { "dependencies": {
"ace-builds": "^1.2.8", "ace-builds": "^1.2.9",
"async": "2.5.0", "async": "2.5.0",
"autoprefixer": "7.1.4", "autoprefixer": "7.1.6",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"benchpressjs": "^1.1.0", "benchpressjs": "^1.1.2",
"body-parser": "^1.18.2", "body-parser": "^1.18.2",
"bootstrap": "^3.3.7", "bootstrap": "^3.3.7",
"chart.js": "^2.6.0", "chart.js": "^2.7.0",
"colors": "^1.1.2", "colors": "^1.1.2",
"compression": "^1.7.1", "compression": "^1.7.1",
"connect-ensure-login": "^0.1.1", "connect-ensure-login": "^0.1.1",
"connect-flash": "^0.1.1", "connect-flash": "^0.1.1",
"connect-mongo": "1.3.2", "connect-mongo": "2.0.0",
"connect-multiparty": "^2.0.0", "connect-multiparty": "^2.1.0",
"connect-redis": "3.3.2", "connect-redis": "3.3.2",
"cookie-parser": "^1.4.3", "cookie-parser": "^1.4.3",
"cron": "^1.2.1", "cron": "^1.3.0",
"cropperjs": "^1.0.0", "cropperjs": "^1.1.3",
"csurf": "^1.9.0", "csurf": "^1.9.0",
"daemon": "^1.1.0", "daemon": "^1.1.0",
"express": "^4.16.1", "express": "^4.16.2",
"express-session": "^1.15.6", "express-session": "^1.15.6",
"express-useragent": "1.0.8", "express-useragent": "1.0.8",
"html-to-text": "3.3.0", "html-to-text": "3.3.0",
"ipaddr.js": "^1.5.2", "ipaddr.js": "^1.5.4",
"jimp": "0.2.28", "jimp": "0.2.28",
"jquery": "^3.2.1", "jquery": "^3.2.1",
"json-2-csv": "^2.1.1", "json-2-csv": "^2.1.2",
"less": "^2.7.2", "less": "^2.7.2",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"logrotate-stream": "^0.2.5", "logrotate-stream": "^0.2.5",
@ -52,7 +52,7 @@
"mime": "^2.0.3", "mime": "^2.0.3",
"minimist": "^1.2.0", "minimist": "^1.2.0",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"mongodb": "2.2.31", "mongodb": "2.2.33",
"morgan": "^1.9.0", "morgan": "^1.9.0",
"mousetrap": "^1.6.1", "mousetrap": "^1.6.1",
"nconf": "^0.8.5", "nconf": "^0.8.5",
@ -70,10 +70,10 @@
"nodebb-theme-slick": "1.1.1", "nodebb-theme-slick": "1.1.1",
"nodebb-theme-vanilla": "7.1.2", "nodebb-theme-vanilla": "7.1.2",
"nodebb-widget-essentials": "3.0.7", "nodebb-widget-essentials": "3.0.7",
"nodemailer": "4.1.1", "nodemailer": "4.3.0",
"passport": "^0.4.0", "passport": "^0.4.0",
"passport-local": "1.0.0", "passport-local": "1.0.0",
"postcss": "6.0.12", "postcss": "6.0.13",
"postcss-clean": "1.1.0", "postcss-clean": "1.1.0",
"promise-polyfill": "^6.0.2", "promise-polyfill": "^6.0.2",
"prompt": "^1.0.0", "prompt": "^1.0.0",
@ -85,30 +85,30 @@
"semver": "^5.4.1", "semver": "^5.4.1",
"serve-favicon": "^2.4.5", "serve-favicon": "^2.4.5",
"sitemap": "^1.13.0", "sitemap": "^1.13.0",
"socket.io": "2.0.3", "socket.io": "2.0.4",
"socket.io-client": "2.0.3", "socket.io-client": "2.0.4",
"socket.io-redis": "5.2.0", "socket.io-redis": "5.2.0",
"socketio-wildcard": "2.0.0", "socketio-wildcard": "2.0.0",
"spdx-license-list": "^3.0.1", "spdx-license-list": "^3.0.1",
"toobusy-js": "^0.5.1", "toobusy-js": "^0.5.1",
"uglify-js": "^3.1.3", "uglify-js": "^3.1.5",
"validator": "9.0.0", "validator": "9.0.0",
"winston": "^2.3.1", "winston": "^2.4.0",
"xml": "^1.0.1", "xml": "^1.0.1",
"xregexp": "3.2.0", "xregexp": "3.2.0",
"zxcvbn": "^4.4.2" "zxcvbn": "^4.4.2"
}, },
"devDependencies": { "devDependencies": {
"coveralls": "^3.0.0", "coveralls": "^3.0.0",
"eslint": "^4.8.0", "eslint": "^4.9.0",
"eslint-config-airbnb-base": "^12.0.1", "eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-import": "^2.7.0", "eslint-plugin-import": "^2.8.0",
"grunt": "^1.0.1", "grunt": "^1.0.1",
"grunt-contrib-watch": "^1.0.0", "grunt-contrib-watch": "^1.0.0",
"istanbul": "^0.4.5",
"jsdom": "^11.3.0", "jsdom": "^11.3.0",
"mocha": "^3.5.3", "mocha": "^4.0.1",
"mocha-lcov-reporter": "^1.3.0" "mocha-lcov-reporter": "^1.3.0",
"nyc": "^11.2.1"
}, },
"bugs": { "bugs": {
"url": "https://github.com/NodeBB/NodeBB/issues" "url": "https://github.com/NodeBB/NodeBB/issues"

@ -65,7 +65,7 @@
"logout": "Log out", "logout": "Log out",
"view-forum": "View Forum", "view-forum": "View Forum",
"search.placeholder": "Search...", "search.placeholder": "Search for settings",
"search.no-results": "No results...", "search.no-results": "No results...",
"search.search-forum": "Search the forum for <strong></strong>", "search.search-forum": "Search the forum for <strong></strong>",
"search.keep-typing": "Type more to see results...", "search.keep-typing": "Type more to see results...",

@ -1,6 +1,6 @@
{ {
"alert.confirm-reload": "Está seguro que desea recargar NodeBB?", "alert.confirm-reload": "¿Está seguro que desea recargar NodeBB?",
"alert.confirm-restart": "Está seguro que desea reiniciar NodeBB?", "alert.confirm-restart": "¿Está seguro que desea reiniciar NodeBB?",
"acp-title": "%1 | Panel de control de administrador NodeBB", "acp-title": "%1 | Panel de control de administrador NodeBB",
"settings-header-contents": "Contenidos" "settings-header-contents": "Contenidos"

@ -5,11 +5,11 @@
"out-of-date": "Périmé", "out-of-date": "Périmé",
"none-found": "Aucun plugin trouvé", "none-found": "Aucun plugin trouvé",
"none-active": "Aucun plugin actif", "none-active": "Aucun plugin actif",
"find-plugins": "Plugins trouvés", "find-plugins": "Chercher des plugins",
"plugin-search": "Recherche de plugin", "plugin-search": "Recherche de plugin",
"plugin-search-placeholder": "Rechercher un plugin…", "plugin-search-placeholder": "Rechercher un plugin…",
"reorder-plugins": "Re-ordonner les plugins", "reorder-plugins": "Réordonner les plugins",
"order-active": "Trier les plugins actifs", "order-active": "Trier les plugins actifs",
"dev-interested": "Êtes-vous intéressés par l'écriture de plugins pour NodeBB ?", "dev-interested": "Êtes-vous intéressés par l'écriture de plugins pour NodeBB ?",
"docs-info": "La documentation complète concernant lécriture de plugin peut être trouvée sur le<a target=\"_blank\" href=\"https://docs.nodebb.org/development/plugins/\">Portail Documentation NodeBB</a>.", "docs-info": "La documentation complète concernant lécriture de plugin peut être trouvée sur le<a target=\"_blank\" href=\"https://docs.nodebb.org/development/plugins/\">Portail Documentation NodeBB</a>.",
@ -47,5 +47,5 @@
"license.title": "Information sur la licence du plugin", "license.title": "Information sur la licence du plugin",
"license.intro": "Le plugin <strong>%1</strong> est sous licence %2. Veuillez lire et comprendre les termes de la licence avant dactiver ce plugin.", "license.intro": "Le plugin <strong>%1</strong> est sous licence %2. Veuillez lire et comprendre les termes de la licence avant dactiver ce plugin.",
"license.cta": "Voulez-vous continuer lactivation de ce plugin ?" "license.cta": "Voulez-vous poursuivre en activant ce plugin ?"
} }

@ -1,11 +1,11 @@
{ {
"post-cache": "Prześlij pamięć podręczną", "post-cache": "Pamięć podręczna postów",
"posts-in-cache": "Postów w pamięci podręcznej", "posts-in-cache": "Posty w pamięci podręcznej",
"average-post-size": "Średnia wielkość posta", "average-post-size": "Średnia wielkość posta",
"length-to-max": "Długość / Maks.", "length-to-max": "Długość / Maks.",
"percent-full": "%1%", "percent-full": "%1%",
"post-cache-size": "Rozmiar pamięci podręcznej posta", "post-cache-size": "Rozmiar pamięci podręcznej postów",
"items-in-cache": "Pozycji w pamięci podręcznej", "items-in-cache": "Elementów w pamięci podręcznej",
"control-panel": "Panel administracyjny", "control-panel": "Panel administracyjny",
"update-settings": "Zaktualizuj ustawienia pamięci podręcznej" "update-settings": "Zaktualizuj ustawienia pamięci"
} }

@ -2,12 +2,12 @@
"x-b": "%1 b", "x-b": "%1 b",
"x-mb": "%1 mb", "x-mb": "%1 mb",
"x-gb": "%1 gb", "x-gb": "%1 gb",
"uptime-seconds": "Uptime w sekundach", "uptime-seconds": "Czas od restartu w sekundach",
"uptime-days": "Uptime w dniach", "uptime-days": "Czas od restartu w dniach",
"mongo": "Mongo", "mongo": "Mongo",
"mongo.version": "Wersja MongoDB", "mongo.version": "Wersja MongoDB",
"mongo.storage-engine": "Silnik Magazynowania", "mongo.storage-engine": "Silnik magazynowania",
"mongo.collections": "Kolekcje", "mongo.collections": "Kolekcje",
"mongo.objects": "Obiekty", "mongo.objects": "Obiekty",
"mongo.avg-object-size": "Przybliżony rozmiar obiektu", "mongo.avg-object-size": "Przybliżony rozmiar obiektu",
@ -15,22 +15,22 @@
"mongo.storage-size": "Rozmiar pamięci", "mongo.storage-size": "Rozmiar pamięci",
"mongo.index-size": "Rozmiar indeksu", "mongo.index-size": "Rozmiar indeksu",
"mongo.file-size": "Rozmiar pliku", "mongo.file-size": "Rozmiar pliku",
"mongo.resident-memory": "Przynależna Pamięć", "mongo.resident-memory": "Pamięć przydzielona",
"mongo.virtual-memory": "Pamięc wirtualna", "mongo.virtual-memory": "Pamięc wirtualna",
"mongo.mapped-memory": "Pamięc zmapowana", "mongo.mapped-memory": "Pamięc zmapowana",
"mongo.raw-info": "Surowe informacje MongoDB", "mongo.raw-info": "Informacje MongoDB",
"redis": "Redis", "redis": "Redis",
"redis.version": "Wersja Redis", "redis.version": "Wersja Redis",
"redis.connected-clients": "Połączonych klientów", "redis.connected-clients": "Połączonych klientów",
"redis.connected-slaves": "Połączonych niewolników", "redis.connected-slaves": "Połączonych urządzeń podrzędnych",
"redis.blocked-clients": "Zablokowanych klientów", "redis.blocked-clients": "Zablokowanych klientów",
"redis.used-memory": "Użyta pamięć", "redis.used-memory": "Użyta pamięć",
"redis.memory-frag-ratio": "Proporcja fragmentacji pamięci", "redis.memory-frag-ratio": "Proporcja fragmentacji pamięci",
"redis.total-connections-recieved": "Otrzymanych połączeń", "redis.total-connections-recieved": "Otrzymanych połączeń",
"redis.total-commands-processed": "Przetworzonych połączeń", "redis.total-commands-processed": "Przetworzonych komend",
"redis.iops": "Natychmiastowe Operacje Na Sekundę", "redis.iops": "Natychmiastowe Operacje Na Sekundę",
"redis.keyspace-hits": "Trafienia Kluczy", "redis.keyspace-hits": "Trafione Klucze",
"redis.keyspace-misses": "Nietrafione Klucze", "redis.keyspace-misses": "Nietrafione Klucze",
"redis.raw-info": "Surowe informacje Redis" "redis.raw-info": "Informacje Redis"
} }

@ -1,11 +1,11 @@
{ {
"figure-x": "Błąd %1", "figure-x": "Błąd %1",
"error-events-per-day": "<code>%1</code> wydarzeń dziennie", "error-events-per-day": "<code>%1</code> zdarzeń dziennie",
"error.404": "404 Nie znaleziono", "error.404": "404 Nie znaleziono",
"error.503": "503 Usługa niedostępna", "error.503": "503 Usługa niedostępna",
"manage-error-log": "Zarządzaj dziennikiem błędów", "manage-error-log": "Zarządzaj dziennikiem błędów",
"export-error-log": "Eksportuj dziennik błędów (CSV)", "export-error-log": "Eksportuj dziennik (CSV)",
"clear-error-log": "Wyczyść dziennik błędów", "clear-error-log": "Wyczyść dziennik",
"route": "Scieżka", "route": "Scieżka",
"count": "Licznik", "count": "Licznik",
"no-routes-not-found": "Hura! Żadnych błędów 404!", "no-routes-not-found": "Hura! Żadnych błędów 404!",

@ -1,5 +1,5 @@
{ {
"events": "Wydarzenia", "events": "Zdarzenia",
"no-events": "Brak zdarzeń", "no-events": "Brak zdarzeń",
"control-panel": "Panel zdarzeń", "control-panel": "Panel zdarzeń",
"delete-events": "Usuń zdarzenia" "delete-events": "Usuń zdarzenia"

@ -1,7 +1,7 @@
{ {
"logs": "Logi", "logs": "Logi",
"control-panel": "Logi Panelu Kontroli", "control-panel": "Logi Panelu Sterowania",
"reload": "Przeładuj logi", "reload": "Przeładuj logi",
"clear": "Wyczyść Logi", "clear": "Wyczyść Logi",
"clear-success": "Logi Wyczyszczone!" "clear-success": "Logi wyczyszczone!"
} }

@ -1,12 +1,12 @@
{ {
"custom-css": "Własny CSS", "custom-css": "Własny CSS",
"custom-css.description": "Wpisz własne deklaracje CSS tutaj, będą one zastosowane do wszystkich styli.", "custom-css.description": "Wprowadź tu własne deklaracje CSS, będą one zastosowane po wszystkich innych stylach.",
"custom-css.enable": "Włącz własne style CSS", "custom-css.enable": "Włącz własne style CSS",
"custom-header": "Własny nagłówek", "custom-header": "Własny nagłówek",
"custom-header.description": "Wpisz tutaj kod HTML (JavaScript, tagi <code>&lt;meta&gt;</code>) który ma być dołączony do sekcji <code>&lt;head&gt;</code> w szablonie forum.", "custom-header.description": "Wpisz tutaj kod HTML (JavaScript, tagi <code>&lt;meta&gt;</code>) który ma być dołączony do sekcji <code>&lt;head&gt;</code> w szablonie forum.",
"custom-header.enable": "Włącz własny nagłówek", "custom-header.enable": "Włącz własny nagłówek",
"custom-css.livereload": "Włącz żywe przeładowanie", "custom-css.livereload": "Włącz dynamiczne przeładowanie",
"custom-css.livereload.description": "Włącz to, aby zmusić wszystkie sesje do odświeżenia na każdym urządzeniu na twoim koncie gdziekolwiek klikniesz zapisz." "custom-css.livereload.description": "Włącz to, aby zmusić wszystkie sesje do odświeżenia na każdym urządzeniu na twoim koncie gdziekolwiek klikniesz zapisz."
} }

@ -1,7 +1,7 @@
{ {
"you-are-on": "Informacja - Jesteś na <strong>%1:%2</strong>", "you-are-on": "Informacja - Jesteś na <strong>%1:%2</strong>",
"nodes-responded": "%1 nodes odpowiedziały w ciągu %2ms!", "nodes-responded": "%1 węzły odpowiedziały w ciągu %2ms!",
"host": "Host", "host": "host",
"pid": "pid", "pid": "pid",
"nodejs": "nodejs", "nodejs": "nodejs",
"online": "online", "online": "online",

@ -8,8 +8,8 @@
"delete": "Usuń", "delete": "Usuń",
"enable": "Włącz", "enable": "Włącz",
"disable": "Wyłącz", "disable": "Wyłącz",
"control-panel": "Ustawienia Nagród", "control-panel": "Ustawienia nagród",
"new-reward": "Nowa Nagroda", "new-reward": "Nowa nagroda",
"alert.delete-success": "Pomyślnie usunięto nagrodę", "alert.delete-success": "Pomyślnie usunięto nagrodę",
"alert.no-inputs-found": "Niepoprawnie dodana nagroda ", "alert.no-inputs-found": "Niepoprawnie dodana nagroda ",

@ -8,12 +8,12 @@
"container.well": "Well", "container.well": "Well",
"container.jumbotron": "Jumbotron", "container.jumbotron": "Jumbotron",
"container.panel": "Panel", "container.panel": "Panel",
"container.panel-header": "Panel nagłówka", "container.panel-header": "Nagłówek panelu",
"container.panel-body": "Zawartość panelu", "container.panel-body": "Zawartość panelu",
"container.alert": "Alarm", "container.alert": "Alarm",
"alert.confirm-delete": "Czy na pewno chcesz usunąć ten widget?", "alert.confirm-delete": "Czy na pewno chcesz usunąć ten widget?",
"alert.updated": "Widżety zaktualizowane", "alert.updated": "Widżety zaktualizowane",
"alert.update-success": "Pomyślnie widżety zostały zaktualizowane" "alert.update-success": "Widżety zostały pomyślnie zaktualizowane"
} }

@ -8,7 +8,7 @@
"page-views-seven": "Ostatnie 7 dni", "page-views-seven": "Ostatnie 7 dni",
"page-views-thirty": "Ostatnie 30 dni", "page-views-thirty": "Ostatnie 30 dni",
"page-views-last-day": "Ostatnie 24 godziny", "page-views-last-day": "Ostatnie 24 godziny",
"page-views-custom": "Własna zakres dat", "page-views-custom": "Własny zakres dat",
"page-views-custom-start": "Początek zakresu", "page-views-custom-start": "Początek zakresu",
"page-views-custom-end": "Koniec zakresu", "page-views-custom-end": "Koniec zakresu",
"page-views-custom-help": "Wprowadź zakres dat dla wyświetl strony, które chciałbyś zobaczyć. Jeśli brakuje możliwości wybory daty, akceptowalny format to <code>YYYY-MM-DD</code>", "page-views-custom-help": "Wprowadź zakres dat dla wyświetl strony, które chciałbyś zobaczyć. Jeśli brakuje możliwości wybory daty, akceptowalny format to <code>YYYY-MM-DD</code>",
@ -33,12 +33,12 @@
"restart-required": "Wymagany restart", "restart-required": "Wymagany restart",
"search-plugin-installed": "Wyszukiwarka jest zainstalowana", "search-plugin-installed": "Wyszukiwarka jest zainstalowana",
"search-plugin-not-installed": "Wyszukiwarka nie jest zainstalowana", "search-plugin-not-installed": "Wyszukiwarka nie jest zainstalowana",
"search-plugin-tooltip": "Zainstaluj wtyczkę wyszukiwania ze strony wtyczek, aby aktywować funkcjonalność szukania", "search-plugin-tooltip": "Zainstaluj wtyczkę wyszukiwania ze strony wtyczek, aby aktywować funkcję szukania",
"control-panel": "Zarządzanie systemem", "control-panel": "Zarządzanie systemem",
"reload": "Odśwież", "reload": "Odśwież",
"restart": "Restart", "restart": "Restart",
"restart-warning": "Przeładowanie lub Restart NodeBB spowoduje przerwanie wszystkich istniejących połączeń na kilka sekund.", "restart-warning": "Przeładowanie lub restart NodeBB spowoduje przerwanie wszystkich istniejących połączeń na kilka sekund.",
"maintenance-mode": "Tryb konserwacji", "maintenance-mode": "Tryb konserwacji",
"maintenance-mode-title": "Kliknij tutaj aby skonfigurować tryb konserwacji dla NodeBB", "maintenance-mode-title": "Kliknij tutaj aby skonfigurować tryb konserwacji dla NodeBB",
"realtime-chart-updates": "Wykresy aktualizowane na żywo", "realtime-chart-updates": "Wykresy aktualizowane na żywo",
@ -60,10 +60,10 @@
"recent": "Ostatnie", "recent": "Ostatnie",
"unread": "Nieprzeczytane", "unread": "Nieprzeczytane",
"high-presence-topics": "Tematy wysokiej obecności", "high-presence-topics": "Popularne tematy",
"graphs.page-views": "Wyświetlenia strony", "graphs.page-views": "Wyświetlenia strony",
"graphs.unique-visitors": "Unikalni Użytkownicy", "graphs.unique-visitors": "Unikalni użytkownicy",
"graphs.registered-users": "Zarejestrowani Użytkownicy", "graphs.registered-users": "Zarejestrowani użytkownicy",
"graphs.anonymous-users": "Anonimowi Użytkownicy" "graphs.anonymous-users": "Anonimowi użytkownicy"
} }

@ -8,8 +8,8 @@
"id": "ID: <small>opcjonalnie</small>", "id": "ID: <small>opcjonalnie</small>",
"properties": "Ustawienia:", "properties": "Ustawienia:",
"only-admins": "Pokazuj tylko administracji", "only-admins": "Pokazuj tylko administratorom",
"only-global-mods-and-admins": "Pokazuj tylko globalnym moderatorom oraz administracji", "only-global-mods-and-admins": "Pokazuj tylko globalnym moderatorom oraz administratorom",
"only-logged-in": "Pokazuj tylko zalogowanym użytkownikom", "only-logged-in": "Pokazuj tylko zalogowanym użytkownikom",
"only-guest": "Pokazuj tylko gościom", "only-guest": "Pokazuj tylko gościom",
"open-new-window": "Otwórz w nowym oknie", "open-new-window": "Otwórz w nowym oknie",
@ -17,12 +17,12 @@
"installed-plugins-required": "Wymagane zainstalowane wtyczki:", "installed-plugins-required": "Wymagane zainstalowane wtyczki:",
"search-plugin": "Wyszukiwarka", "search-plugin": "Wyszukiwarka",
"btn.delete": "Usunąć", "btn.delete": "Usuń",
"btn.disable": "Wyłącz", "btn.disable": "Wyłącz",
"btn.enable": "Włącz", "btn.enable": "Włącz",
"available-menu-items": "Dostępne obiekty menu", "available-menu-items": "Dostępne obiekty menu",
"custom-route": "Niestandardowa ścieżka", "custom-route": "Niestandardowa ścieżka",
"core": "core", "core": "system",
"plugin": "wtyczka" "plugin": "wtyczka"
} }

@ -1,5 +1,5 @@
{ {
"post-sharing": "Udostępnianie postów", "post-sharing": "Udostępnianie postów",
"info-plugins-additional": "Wtyczki mogą dodać dodatkowe platformy do udostępniania postów", "info-plugins-additional": "Wtyczki mogą dodać dodatkowe platformy do udostępniania postów",
"save-success": "Pomyślnie zapisano sieci udostępniania postów!" "save-success": "Pomyślnie zapisano!"
} }

@ -1,9 +1,9 @@
{ {
"notifications": "Powiadomienia", "notifications": "Powiadomienia",
"chat-messages": "Wiadomości czatu", "chat-messages": "Wiadomości czatu",
"play-sound": "Otwórz", "play-sound": "Odtwórz",
"incoming-message": "Przychodzące wiadomości", "incoming-message": "Przychodzące wiadomości",
"outgoing-message": "Wychodzące wiadomości", "outgoing-message": "Wychodzące wiadomości",
"upload-new-sound": "Prześlij nowy dźwięk", "upload-new-sound": "Prześlij nowy dźwięk",
"saved": "Ustawienia Zapisane" "saved": "Ustawienia zapisane"
} }

@ -10,9 +10,9 @@
"custom-class": "Niestandardowa klasa", "custom-class": "Niestandardowa klasa",
"num-recent-replies": "# z ostatnich odpowiedzi", "num-recent-replies": "# z ostatnich odpowiedzi",
"ext-link": "Zewnętrzny odnośnik", "ext-link": "Zewnętrzny odnośnik",
"is-section": "Traktuj tą kategorię jako sekcję", "is-section": "Traktuj tę kategorię jako sekcję",
"upload-image": "Prześlij obrazek", "upload-image": "Prześlij obrazek",
"delete-image": "Usunąć", "delete-image": "Usuń",
"category-image": "Obrazek kategorii", "category-image": "Obrazek kategorii",
"parent-category": "Kategoria nadrzędna", "parent-category": "Kategoria nadrzędna",
"optional-parent-category": "(Opcjonalne) Kategoria nadrzędna", "optional-parent-category": "(Opcjonalne) Kategoria nadrzędna",
@ -21,8 +21,8 @@
"optional-clone-settings": "(Opcjonalnie) Spoiowanie ustawień z kategorii", "optional-clone-settings": "(Opcjonalnie) Spoiowanie ustawień z kategorii",
"purge": "Usuń kategorię", "purge": "Usuń kategorię",
"enable": "Włączona", "enable": "Włącz",
"disable": "Wyłączona", "disable": "Wyłącz",
"edit": "Edytuj", "edit": "Edytuj",
"select-category": "Wybierz kategorię", "select-category": "Wybierz kategorię",
@ -50,10 +50,10 @@
"analytics.topics-daily": "<strong>Ilustracja 3</strong>&ndash; Dzienne tematy tworzone w tej kategorii</small>", "analytics.topics-daily": "<strong>Ilustracja 3</strong>&ndash; Dzienne tematy tworzone w tej kategorii</small>",
"analytics.posts-daily": "<strong>Ilustracja 4</strong> &ndash; Dzienne posty pisane w tej kategorii</small>", "analytics.posts-daily": "<strong>Ilustracja 4</strong> &ndash; Dzienne posty pisane w tej kategorii</small>",
"alert.created": "Stworzony", "alert.created": "Utworzony",
"alert.create-success": "Kategoria pomyślnie dodana!", "alert.create-success": "Kategoria pomyślnie dodana!",
"alert.none-active": "Nie masz aktywnych kategorii.", "alert.none-active": "Nie masz aktywnych kategorii.",
"alert.create": "Stwórz kategorie", "alert.create": "Utwórz kategorię",
"alert.confirm-moderate": "<strong>Czy jesteś pewien, że chcesz udzielić uprawnień moderatorskich dla tej grupy użytkowników?</strong>Ta grupa jest publiczna i każdy użytkownik może do niej dołączyć.", "alert.confirm-moderate": "<strong>Czy jesteś pewien, że chcesz udzielić uprawnień moderatorskich dla tej grupy użytkowników?</strong>Ta grupa jest publiczna i każdy użytkownik może do niej dołączyć.",
"alert.confirm-purge": "<p class=\"lead\">Czy na pewno chcesz wymazać tą kategorię \"%1\"?</p><h5><strong class=\"text-danger\">Uwaga!</strong> Wszystkie tematy oraz posty z tej kategorii zostaną wymazane!</h5><p class=\"help-block\">Wymazanie kategorii skasuje wszystkie tematy, posty oraz skasuję kategorię z bazy danych. Jeśli chcesz <em>tymczasowo</em>usunąć kategorię, będziesz musiał \"wyłączyć\" kategorię.</p>", "alert.confirm-purge": "<p class=\"lead\">Czy na pewno chcesz wymazać tą kategorię \"%1\"?</p><h5><strong class=\"text-danger\">Uwaga!</strong> Wszystkie tematy oraz posty z tej kategorii zostaną wymazane!</h5><p class=\"help-block\">Wymazanie kategorii skasuje wszystkie tematy, posty oraz skasuję kategorię z bazy danych. Jeśli chcesz <em>tymczasowo</em>usunąć kategorię, będziesz musiał \"wyłączyć\" kategorię.</p>",
"alert.purge-success": "Kategoria usunięta!", "alert.purge-success": "Kategoria usunięta!",
@ -63,7 +63,7 @@
"alert.updated-success": "ID kategorii %1 pomyślnie zaktualizowano.", "alert.updated-success": "ID kategorii %1 pomyślnie zaktualizowano.",
"alert.upload-image": "Prześlij obrazek kategorii", "alert.upload-image": "Prześlij obrazek kategorii",
"alert.find-user": "Znajdź użytkownika", "alert.find-user": "Znajdź użytkownika",
"alert.user-search": "Szukaj użytkownika tutaj...", "alert.user-search": "Wyszukaj użytkownika tutaj...",
"alert.find-group": "Szukaj grupę", "alert.find-group": "Znajdź grupę",
"alert.group-search": "Szukaj grupę tutaj..." "alert.group-search": "Wyszukaj grupę tutaj..."
} }

@ -2,12 +2,12 @@
"name": "Nazwa grupy", "name": "Nazwa grupy",
"description": "Opis grupy", "description": "Opis grupy",
"member-count": "Liczba użytkowników", "member-count": "Liczba użytkowników",
"system": "System grup", "system": "Grupa systemowa",
"edit": "Edytuj", "edit": "Edytuj",
"search-placeholder": "Szukaj", "search-placeholder": "Szukaj",
"create": "Stwórz Grupę", "create": "Utwórz grupę",
"description-placeholder": "Krótki opisz grupy", "description-placeholder": "Krótki opis grupy",
"create-button": "Stwórz", "create-button": "Utwórz",
"alerts.create-failure": "<strong>Uh-Oh</strong><p>Wystąpił problem podczas tworzenia grupy. Spróbuj ponownie później</p>", "alerts.create-failure": "<strong>Uh-Oh</strong><p>Wystąpił problem podczas tworzenia grupy. Spróbuj ponownie później</p>",
"alerts.confirm-delete": "Czy na pewno chcesz usunąć tę grupę?", "alerts.confirm-delete": "Czy na pewno chcesz usunąć tę grupę?",
@ -16,7 +16,7 @@
"edit.description": "Opis", "edit.description": "Opis",
"edit.user-title": "Tytuł członków ", "edit.user-title": "Tytuł członków ",
"edit.icon": "Ikona grupy", "edit.icon": "Ikona grupy",
"edit.label-color": "Kolor Etykiety Grupy", "edit.label-color": "Kolor etykiety grupy",
"edit.show-badge": "Pokazuj odznakę", "edit.show-badge": "Pokazuj odznakę",
"edit.private-details": "Jeśli włączone, przystępowanie do grup wymaga zatwierdzenia przez właściciela grupy", "edit.private-details": "Jeśli włączone, przystępowanie do grup wymaga zatwierdzenia przez właściciela grupy",
"edit.private-override": "Ostrzeżenie: Prywatne grupy są wyłączone w ustawieniach, co powoduje przesłonięcia opcji.", "edit.private-override": "Ostrzeżenie: Prywatne grupy są wyłączone w ustawieniach, co powoduje przesłonięcia opcji.",

@ -1,12 +1,12 @@
{ {
"lead": "Tutaj skonfigurują swoją czarną listę IP.", "lead": "Tutaj skonfiguruj swoją czarną listę IP.",
"description": "Czasami ban konta użytkownika nie jest wystarczającym odstraszaczem i wtedy ograniczanie dostępu do forum dla konkretnego adresu IP lub zakresu adresów IP, są najlepszymi metodami ochrony forum. W tym przypadkach, możesz dodać adresy UP lub całe bloki CIDR do tej czarnej listy i będą one ograniczały możliwość logowania na forum lub rejestracji nowych kont.", "description": "Czasami ban konta użytkownika nie jest wystarczającym zabezpieczeniem. Wtedy ograniczanie dostępu do forum dla konkretnego adresu IP lub zakresu adresów IP jest najlepszą metodą ochrony forum. W tym przypadku możesz dodać adresy IP lub całe bloki CIDR do czarnej listy i będą one miały zablokowaną możliwość logowania na forum lub rejestracji nowych kont.",
"active-rules": "Aktywne reguły", "active-rules": "Aktywne reguły",
"validate": "Sprawdzanie czarnej listy", "validate": "Sprawdzanie czarnej listy",
"apply": "Zastosuj czarną listę", "apply": "Zastosuj czarną listę",
"hints": "Podpowiedzi składni", "hints": "Podpowiedzi składni",
"hint-1": "W każdej linii zdefiniuj pojedynczy adres IP. Możesz dodać bloki IP pod warunkiem, że spełniają one wymagania formatu CIDR (np. <code>192.168.100.0/22</code>).", "hint-1": "W każdej linii zdefiniuj pojedynczy adres IP. Możesz dodać bloki IP pod warunkiem, że spełniają one wymagania formatu CIDR (np. <code>192.168.100.0/22</code>).",
"hint-2": "Możesz dodawać komentarze porze rozpoczęcie linii symbolem <code>#</code>.", "hint-2": "Możesz dodawać komentarze poprzez rozpoczęcie linii symbolem <code>#</code>.",
"validate.x-valid": "<strong>%1</strong> z <strong>%2</strong> reguła(-u) są poprawne.", "validate.x-valid": "<strong>%1</strong> z <strong>%2</strong> reguła(-u) są poprawne.",
"validate.x-invalid": "Następujące <strong>%1</strong> reguły są niewłaściwe:", "validate.x-invalid": "Następujące <strong>%1</strong> reguły są niewłaściwe:",

@ -1,9 +1,9 @@
{ {
"none": "Twoje forum nie ma jeszcze żadnych tematów z tagami.", "none": "Twoje forum nie ma jeszcze żadnych tematów z tagami.",
"bg-color": "Kolor tła", "bg-color": "Kolor tła",
"text-color": "Kolor Tekstu", "text-color": "Kolor tekstu",
"create-modify": "Utwórz oraz modyfikuj tagi", "create-modify": "Utwórz oraz modyfikuj tagi",
"description": "Wybierz tagi poprzez klikanie oraz/lub przeciąganie, użyj przycisku shift do zaznaczenia wielu.", "description": "Wybierz tagi poprzez klikanie lub przeciąganie, użyj przycisku shift do zaznaczenia wielu.",
"create": "Utwórz tag", "create": "Utwórz tag",
"modify": "Modyfikuj tagi", "modify": "Modyfikuj tagi",
"delete": "Usuń zaznaczone tagi", "delete": "Usuń zaznaczone tagi",

@ -1,8 +1,8 @@
{ {
"users": "Użytkownicy", "users": "Użytkownicy",
"edit": "Edytuj", "edit": "Edytuj",
"make-admin": "Nadaj Admina", "make-admin": "Nadaj uprawnienia administratora",
"remove-admin": "Odbierz Admin", "remove-admin": "Odbierz uprawnienia administratora",
"validate-email": "Zweryfikuj email", "validate-email": "Zweryfikuj email",
"send-validation-email": "Wyślij email weryfikacyjny", "send-validation-email": "Wyślij email weryfikacyjny",
"password-reset-email": "Wyślij email resetowania hasła", "password-reset-email": "Wyślij email resetowania hasła",
@ -11,7 +11,7 @@
"unban": "Odbanuj użytkownika(-ów)", "unban": "Odbanuj użytkownika(-ów)",
"reset-lockout": "Zresetuj blokadę", "reset-lockout": "Zresetuj blokadę",
"reset-flags": "Zresetuj flagi", "reset-flags": "Zresetuj flagi",
"delete": "Skasuj użytkownika(-ów)", "delete": "Usuń użytkownika(-ów)",
"purge": "Usuń użytkownika(-ów) oraz zawartość", "purge": "Usuń użytkownika(-ów) oraz zawartość",
"download-csv": "Pobierz CSV", "download-csv": "Pobierz CSV",
"invite": "Zaproś", "invite": "Zaproś",
@ -22,10 +22,10 @@
"pills.no-posts": "Brak postów", "pills.no-posts": "Brak postów",
"pills.top-posters": "Najwięcej postów", "pills.top-posters": "Najwięcej postów",
"pills.top-rep": "Najlepsza reputacja", "pills.top-rep": "Najlepsza reputacja",
"pills.inactive": "Nieaktywny(-a)", "pills.inactive": "Nieaktywny",
"pills.flagged": "Najwięcej flag", "pills.flagged": "Najwięcej flag",
"pills.banned": "Zbanowany(-a)", "pills.banned": "Zbanowany",
"pills.search": "Wyszukiwanie użytkownków", "pills.search": "Wyszukiwanie użytkowników",
"search.username": "Po nazwie użytkownika", "search.username": "Po nazwie użytkownika",
"search.username-placeholder": "Wpisz nazwę użytkownika, aby wyszukać", "search.username-placeholder": "Wpisz nazwę użytkownika, aby wyszukać",
@ -40,14 +40,14 @@
"inactive.12-months": "12 miesięcy", "inactive.12-months": "12 miesięcy",
"users.uid": "uid", "users.uid": "uid",
"users.username": "Nazwa użytkownika", "users.username": "nazwa użytkownika",
"users.email": "Adres e-mail", "users.email": "adres e-mail",
"users.postcount": "Liczba postów", "users.postcount": "liczba postów",
"users.reputation": "reputacja", "users.reputation": "reputacja",
"users.flags": "Flagi", "users.flags": "flagi",
"users.joined": "Dołączono", "users.joined": "dołączono",
"users.last-online": "Ostatnio online", "users.last-online": "ostatnio online",
"users.banned": "Zbanowany(-a)", "users.banned": "zbanowany",
"create.username": "Nazwa użytkownika", "create.username": "Nazwa użytkownika",
"create.email": "Adres e-mail", "create.email": "Adres e-mail",
@ -59,10 +59,10 @@
"temp-ban.reason": "Powód <span class=\"text-muted\">(Opcjonalnie)</span>", "temp-ban.reason": "Powód <span class=\"text-muted\">(Opcjonalnie)</span>",
"temp-ban.hours": "Godzin(-a/-y)", "temp-ban.hours": "Godzin(-a/-y)",
"temp-ban.days": "Dzień/Dni", "temp-ban.days": "Dzień/Dni",
"temp-ban.explanation": "Wprowadzać długość (czas trwania) bana. Długość równa 0 będzie traktowana jako ban permanentny,", "temp-ban.explanation": "Wprowadź długość (czas trwania) bana. Długość równa 0 będzie traktowana jako ban permanentny,",
"alerts.confirm-ban": "Czy na pewno chcesz zbanować tego użytkownika <strong>pernamentnie</strong>?", "alerts.confirm-ban": "Czy na pewno chcesz zbanować tego użytkownika <strong>permanentnie</strong>?",
"alerts.confirm-ban-multi": "\nCzy na pewno chcesz zbanować tych użytkowników <strong>pernamentnie</strong>?", "alerts.confirm-ban-multi": "Czy na pewno chcesz zbanować tych użytkowników <strong>permanentnie</strong>?",
"alerts.ban-success": "Użytkownik(-cy) zostali zbanowani!", "alerts.ban-success": "Użytkownik(-cy) zostali zbanowani!",
"alerts.button-ban-x": "Zbanowano %1 użytkownika (-ów)", "alerts.button-ban-x": "Zbanowano %1 użytkownika (-ów)",
"alerts.unban-success": "Użytkownik(-cy) nie są już zbanowani!", "alerts.unban-success": "Użytkownik(-cy) nie są już zbanowani!",
@ -75,11 +75,11 @@
"alerts.confirm-validate-email": "Czy chcesz zweryfikować email(-e) tego użytkownika (-ów)?", "alerts.confirm-validate-email": "Czy chcesz zweryfikować email(-e) tego użytkownika (-ów)?",
"alerts.validate-email-success": "Zweryfikowano adresy email", "alerts.validate-email-success": "Zweryfikowano adresy email",
"alerts.password-reset-confirm": "Czy chcesz wysłać email (-e) resetujące hasło tego użytkownika(-ów)?", "alerts.password-reset-confirm": "Czy chcesz wysłać email (-e) resetujące hasło tego użytkownika(-ów)?",
"alerts.confirm-delete": "<b>Uwaga!</b><br/>Czy na pewno chcesz skasować użytkownika(-ów)?<br/>Ta akcja jest nieodwracalna! Zostanie skasowane tylko konto użytkownika, jego posty oraz tematy pozostaną niezmienione.", "alerts.confirm-delete": "<b>Uwaga!</b><br/>Czy na pewno chcesz skasować użytkownika(-ów)?<br/>Ta operacja jest nieodwracalna! Zostanie skasowane tylko konto użytkownika, jego posty oraz tematy pozostaną niezmienione.",
"alerts.delete-success": "Użytkownik(-cy) zostali skasowani!", "alerts.delete-success": "Użytkownik(-cy) zostali skasowani!",
"alerts.confirm-purge": "<b>Uwaga!</b><br/>Czy na pewno chcesz skasować użytkownika(-ów) oraz ich zawartość?<br/>Ta akcja jest nieodwracalna! Wszystkie dane użytkownika oraz jego zawartość zostaną wymazane.", "alerts.confirm-purge": "<b>Uwaga!</b><br/>Czy na pewno chcesz skasować użytkownika(-ów) oraz ich zawartość?<br/>Ta akcja jest nieodwracalna! Wszystkie dane użytkownika oraz jego zawartość zostaną wymazane.",
"alerts.create": "Stwórz użytkownika", "alerts.create": "Utwórz użytkownika",
"alerts.button-create": "Stwórz", "alerts.button-create": "Utwórz",
"alerts.button-cancel": "Anuluj", "alerts.button-cancel": "Anuluj",
"alerts.error-passwords-different": "Hasła muszą być takie same!", "alerts.error-passwords-different": "Hasła muszą być takie same!",
"alerts.error-x": "<strong>Błąd</strong><p>%1</p>", "alerts.error-x": "<strong>Błąd</strong><p>%1</p>",

@ -1,6 +1,6 @@
{ {
"section-general": "Ogólne", "section-general": "Ogólne",
"general/dashboard": "Deska rozdzielcza", "general/dashboard": "Pulpit menedżerski",
"general/homepage": "Strona startowa", "general/homepage": "Strona startowa",
"general/navigation": "Nawigacja", "general/navigation": "Nawigacja",
"general/languages": "Języki", "general/languages": "Języki",
@ -20,24 +20,24 @@
"settings/general": "Ogólne", "settings/general": "Ogólne",
"settings/reputation": "Reputacja", "settings/reputation": "Reputacja",
"settings/email": "Email", "settings/email": "Email",
"settings/user": "Użytkownik", "settings/user": "Użytkownicy",
"settings/group": "Grupa", "settings/group": "Grupy",
"settings/guest": "Gość", "settings/guest": "Goście",
"settings/uploads": "Przesłane", "settings/uploads": "Przesyłanie plików",
"settings/post": "Posty", "settings/post": "Posty",
"settings/chat": "Czat", "settings/chat": "Czaty",
"settings/pagination": "Paginacja", "settings/pagination": "Paginacja",
"settings/tags": "Tagi", "settings/tags": "Tagi",
"settings/notifications": "Powiadomienia", "settings/notifications": "Powiadomienia",
"settings/cookies": "Ciasteczka", "settings/cookies": "Ciasteczka",
"settings/web-crawler": "Roboty internetowe", "settings/web-crawler": "Roboty internetowe",
"settings/sockets": "Sockets", "settings/sockets": "Sockety",
"settings/advanced": "Zaawansowane", "settings/advanced": "Zaawansowane",
"settings.page-title": "%1 Ustawienia", "settings.page-title": "%1 Ustawienia",
"section-appearance": "Wygląd", "section-appearance": "Wygląd",
"appearance/themes": "Style", "appearance/themes": "Motywy",
"appearance/skins": "Skórki", "appearance/skins": "Skórki",
"appearance/customise": "Niestandardowy HTML & CSS", "appearance/customise": "Niestandardowy HTML & CSS",
@ -46,27 +46,27 @@
"extend/widgets": "Widgety", "extend/widgets": "Widgety",
"extend/rewards": "Nagrody", "extend/rewards": "Nagrody",
"section-social-auth": "Alternatywne Logowanie", "section-social-auth": "Alternatywne logowanie",
"section-plugins": "Wtyczki", "section-plugins": "Wtyczki",
"extend/plugins.install": "Zainstalowane wtyczki", "extend/plugins.install": "Zainstalowane wtyczki",
"section-advanced": "Zaawansowane", "section-advanced": "Zaawansowane",
"advanced/database": "Baza Danych", "advanced/database": "Baza danych",
"advanced/events": "Wydarzenia", "advanced/events": "Zdarzenia",
"advanced/logs": "Logi", "advanced/logs": "Logi",
"advanced/errors": "Błędy", "advanced/errors": "Błędy",
"advanced/cache": "Pamięć", "advanced/cache": "Pamięć",
"development/logger": "Loger", "development/logger": "Loger",
"development/info": "Informacja", "development/info": "Informacja",
"reload-forum": "Przeładuj Forum", "reload-forum": "Przeładuj forum",
"restart-forum": "Restartuj forum", "restart-forum": "Restartuj forum",
"logout": "Wyloguj się", "logout": "Wyloguj się",
"view-forum": "Zobacz Forum", "view-forum": "Zobacz forum",
"search.placeholder": "Szukaj...", "search.placeholder": "Szukaj...",
"search.no-results": "Brak rezultatów...", "search.no-results": "Brak wyników...",
"search.search-forum": "Szukaj w forum <strong></strong>", "search.search-forum": "Szukaj w forum <strong></strong>",
"search.keep-typing": "Wpisz więcej, aby zobaczyć wyniki ...", "search.keep-typing": "Wpisz więcej, aby zobaczyć wyniki ...",
"search.start-typing": "Zacznij pisać, aby zobaczyć wyniki ...", "search.start-typing": "Zacznij pisać, aby zobaczyć wyniki ...",

@ -1,7 +1,7 @@
{ {
"maintenance-mode": "Tryb konserwacji", "maintenance-mode": "Tryb konserwacji",
"maintenance-mode.help": "Kiedy forum jest w trybie konserwacji, wszystkie żądania będą przekierowane do statycznej strony oczekiwania. Administratorzy nie są objęci tym przekierowaniem i mogą normalnie korzystać ze strony.", "maintenance-mode.help": "Kiedy forum jest w trybie konserwacji, wszystkie żądania będą przekierowane do statycznej strony oczekiwania. Administratorzy nie są objęci tym przekierowaniem i mogą normalnie korzystać ze strony.",
"maintenance-mode.message": "Wiadomość podczas konserwacji", "maintenance-mode.message": "Komunikat na ekranie konserwacji",
"headers": "Nagłówek", "headers": "Nagłówek",
"headers.allow-from": "Ustaw ALLOW-FROM, aby umieścić NodeBB w ramce iFrame", "headers.allow-from": "Ustaw ALLOW-FROM, aby umieścić NodeBB w ramce iFrame",
"headers.powered-by": "Dopasuj nagłówek \"Powered By\" wysyłany przez NodeBB", "headers.powered-by": "Dopasuj nagłówek \"Powered By\" wysyłany przez NodeBB",
@ -10,7 +10,7 @@
"headers.acam": "Access-Control-Allow-Methods", "headers.acam": "Access-Control-Allow-Methods",
"headers.acah": "Access-Control-Allow-Headers", "headers.acah": "Access-Control-Allow-Headers",
"traffic-management": "Zarządzanie ruchem", "traffic-management": "Zarządzanie ruchem",
"traffic.help": "NodeBB jest dostarczane z modułem, który automatycznie blokuje żądania w sytuacjach wysokiego ruchu. Tutaj możesz zmienić te ustawienia, ale ustawienia początkowe są dobrym punktem wyjścia w większości sytuacji.", "traffic.help": "System NodeBB jest dostarczany z modułem, który automatycznie blokuje żądania w przypadku nadmiernego ruchu. Tutaj możesz zmienić te ustawienia, ale ustawienia początkowe są dobrym punktem wyjścia w większości sytuacji.",
"traffic.enable": "Włącz zarządzanie ruchem", "traffic.enable": "Włącz zarządzanie ruchem",
"traffic.event-lag": "Próg opóźnienia pętli zdarzeń (w milisekundach)", "traffic.event-lag": "Próg opóźnienia pętli zdarzeń (w milisekundach)",
"traffic.event-lag-help": "Obniżenie tej wartości spowoduje krótsze ładowanie stron, ale równocześnie wyświetli komunikat \"excessive load\" dla większej liczby użytkowników (wymagany restart).", "traffic.event-lag-help": "Obniżenie tej wartości spowoduje krótsze ładowanie stron, ale równocześnie wyświetli komunikat \"excessive load\" dla większej liczby użytkowników (wymagany restart).",

@ -1,37 +1,37 @@
{ {
"email-settings": "Ustawienia Poczty", "email-settings": "Ustawienia poczty",
"address": "Adres Email", "address": "Adres email",
"address-help": "Ten adres email referuje do adresu, który odbiora zobaczy w polach \"Od\" oraz \"Odpowiedz do\" wiadomości email.", "address-help": "Ten adres email odbiorca zobaczy w polach \"Od\" oraz \"Odpowiedz do\" wiadomości email.",
"from": "Pole Od", "from": "Pole Od",
"from-help": "Nazwa \"Od\" widoczna w wiadomościach email", "from-help": "Nazwa \"Od\" widoczna w wiadomościach email",
"smtp-transport": "Transport SMTP", "smtp-transport": "Transport SMTP",
"smtp-transport.enabled": "Używaj zewnętrznego serwera email, aby wysyłać wiadomości email.", "smtp-transport.enabled": "Używaj zewnętrznego serwera email, aby wysyłać wiadomości email.",
"smtp-transport-help": "Możesz wybrać z listy dobrze znanych usług lub wprowadzić własne.", "smtp-transport-help": "Możesz wybrać z listy dobrze znanych usług lub wprowadzić własne ustawienia.",
"smtp-transport.service": "Wybierz usługę", "smtp-transport.service": "Wybierz usługę",
"smtp-transport.service-custom": "Własna usługa", "smtp-transport.service-custom": "Usługa niestandardowa",
"smtp-transport.service-help": "Wybierz nazwę usługi powyżej w celu wykorzystania jej parametrów. Alternatywnie, wybierz \"Własna usługa\" i wpisz szczegóły poniżej.", "smtp-transport.service-help": "Wybierz nazwę usługi powyżej w celu wykorzystania jej parametrów. Alternatywnie, wybierz \"Własna usługa\" i wpisz szczegóły poniżej.",
"smtp-transport.gmail-warning1": "Zdarzały się raporty dot. usługi Gmail nie działającej na kontach z podwyższonym bezpieczeństwem. W takim przypadku będziesz musiał <a href=\"https://www.google.com/settings/security/lesssecureapps\">skonfigurować swoje konto Gmail, aby dopuszczało mniej bezpieczne aplikacji</a>. ", "smtp-transport.gmail-warning1": "Zdarzały się raporty dot. usługi Gmail nie działającej na kontach z podwyższonym bezpieczeństwem. W takim przypadku będziesz musiał <a href=\"https://www.google.com/settings/security/lesssecureapps\">skonfigurować swoje konto Gmail, aby dopuszczało mniej bezpieczne aplikacji</a>. ",
"smtp-transport.gmail-warning2": "W celu uzyskania dalszych informacji o tym rozwiązaniu, proszę zapoznać się z artykułem NodeMailer dot. tego zagadnienia.</a>Alternatywą byłoby wykorzystanie zewnętrznej wtyczki obsługi email np. SendGrid, Mailgun itp. <a href=\"{config.relative_path}/admin/extend/plugins\">Przeglądaj dostępne wtyczki tyutaj</a>.", "smtp-transport.gmail-warning2": "W celu uzyskania dalszych informacji o tym rozwiązaniu, proszę zapoznać się z artykułem NodeMailer dot. tego zagadnienia.</a>Alternatywą byłoby wykorzystanie zewnętrznej wtyczki obsługi email np. SendGrid, Mailgun itp. <a href=\"{config.relative_path}/admin/extend/plugins\">Przeglądaj dostępne wtyczki tyutaj</a>.",
"smtp-transport.host": "Host SMTP", "smtp-transport.host": "Host SMTP",
"smtp-transport.port": "Port SMTP", "smtp-transport.port": "Port SMTP",
"smtp-transport.security": "Connection security", "smtp-transport.security": "Bezpieczeństwo połączenia",
"smtp-transport.security-encrypted": "Encrypted", "smtp-transport.security-encrypted": "Szyfrowane",
"smtp-transport.security-starttls": "StartTLS", "smtp-transport.security-starttls": "StartTLS",
"smtp-transport.security-none": "None", "smtp-transport.security-none": "Bez szyfrowania",
"smtp-transport.username": "Nazwa użytkownika", "smtp-transport.username": "Nazwa użytkownika",
"smtp-transport.username-help": "<b>Dla usługi Gmail</b> wprowadź tutaj pełny adres email, w szczególności jeśli korzystasz z domeny zrządzanej przez G Suite.", "smtp-transport.username-help": "<b>Dla usługi Gmail</b> wprowadź tutaj pełny adres email, w szczególności jeśli korzystasz z domeny zrządzanej przez G Suite.",
"smtp-transport.password": "Hasło", "smtp-transport.password": "Hasło",
"template": "Edytuj szablon email-a", "template": "Edytuj szablon email-a",
"template.select": "Wybierz szablon email-a", "template.select": "Wybierz szablon email-a",
"template.revert": "Przywróć orginał", "template.revert": "Przywróć oryginalny szablon",
"testing": "Testowanie email", "testing": "Testowanie email",
"testing.select": "Wybierz szablon email-a", "testing.select": "Wybierz szablon email-a",
"testing.send": "Wyślij testowy email", "testing.send": "Wyślij testowy email",
"testing.send-help": "Wiadomość testowa email zostanie wysłana na adres aktualnie zalogowanego użytkownika.", "testing.send-help": "Wiadomość testowa email zostanie wysłana na adres aktualnie zalogowanego użytkownika.",
"subscriptions": "Subskrypcje email", "subscriptions": "Subskrypcje email",
"subscriptions.disable": "Wyłącz emaile powiadomień subskrybentów", "subscriptions.disable": "Wyłącz powiadomienia subskrybentów",
"subscriptions.hour": "Godzina podsumowania", "subscriptions.hour": "Godzina podsumowania",
"subscriptions.hour-help": "Proszę wprowadzić liczbę odpowiadającej godzinie, o które ma być planowane wysłanie mailowego przeglądu (np. <code>0</code> dla północy lub <code>17</code> dla 17:00). Należy pamiętać, że godzina jest godziną serwera i nie koniecznie musi odpowiadać czasowi lokalnemu administratora. Przybliżony czas serwera teraz to: <span id=\"serverTime\"></span><br />Następny przegląd mailowy jest zaplanowany do wysłania o <span id=\"nextDigestTime\"></span>" "subscriptions.hour-help": "Proszę wprowadzić liczbę odpowiadającej godzinie, o które ma być planowane wysłanie mailowego przeglądu (np. <code>0</code> dla północy lub <code>17</code> dla 17:00). Należy pamiętać, że godzina jest godziną serwera i nie koniecznie musi odpowiadać czasowi lokalnemu administratora. Przybliżony czas serwera teraz to: <span id=\"serverTime\"></span><br />Następny przegląd mailowy jest zaplanowany do wysłania o <span id=\"nextDigestTime\"></span>"
} }

@ -3,12 +3,12 @@
"title": "Tytuł strony", "title": "Tytuł strony",
"title.url": "URL", "title.url": "URL",
"title.url-placeholder": "Adres URL strony tytułowej", "title.url-placeholder": "Adres URL strony tytułowej",
"title.url-help": "W momencie kliknięcia na tytule, wysyłaj użytkownika na ten adres. Jeśli pozostawione puste, użytkownik będzie wysyłany do indeksu forum.", "title.url-help": "W momencie kliknięcia na tytule, użytkownik zostanie przeniesiony na ten adres. Jeśli to pole będzie puste, użytkownik zostanie przeniesiony do strony głównej forum.",
"title.name": "Nazwa twojej społeczności", "title.name": "Nazwa twojej społeczności",
"title.show-in-header": "Pokazuj tytuł strony w nagłówku", "title.show-in-header": "Pokazuj tytuł strony w nagłówku",
"browser-title": "Tytuł karty przeglądarki", "browser-title": "Tytuł karty przeglądarki",
"browser-title-help": "Jeśli nie wyspecyfikowano tytułu karty przeglądarki, zostanie użyty tytuł strony", "browser-title-help": "Jeśli nie wyspecyfikowano tytułu karty przeglądarki, zostanie użyty tytuł strony",
"title-layout": "Ułożenie tytułu", "title-layout": "Struktura tytułu karty przeglądarki",
"title-layout-help": "Zdefiniuj strukturę, jaką będzie miał tytuł karty przeglądarki np. &#123;pageTitle&#125; | &#123;browserTitle&#125;", "title-layout-help": "Zdefiniuj strukturę, jaką będzie miał tytuł karty przeglądarki np. &#123;pageTitle&#125; | &#123;browserTitle&#125;",
"description.placeholder": "Krótki opis twojej społeczności", "description.placeholder": "Krótki opis twojej społeczności",
"description": "Opis strony", "description": "Opis strony",
@ -20,7 +20,7 @@
"logo.upload": "Prześlij", "logo.upload": "Prześlij",
"logo.url": "Adres URL", "logo.url": "Adres URL",
"logo.url-placeholder": "Adres URL logo strony", "logo.url-placeholder": "Adres URL logo strony",
"logo.url-help": "W momencie kliknięcia na logo, wysyłaj użytkownika na ten adres. Jeśli pozostawione puste, użytkownik będzie wysyłany do indeksu forum.", "logo.url-help": "W momencie kliknięcia na logo, użytkownik zostanie przeniesiony na ten adres. Jeśli to pole będzie puste, użytkownik zostanie przeniesiony do strony głównej forum.",
"logo.alt-text": "Cały tekst", "logo.alt-text": "Cały tekst",
"log.alt-text-placeholder": "Alternatywny tekst dla dostępności", "log.alt-text-placeholder": "Alternatywny tekst dla dostępności",
"favicon": "Favikona", "favicon": "Favikona",

@ -1,8 +1,8 @@
{ {
"general": "Ogólne", "general": "Ogólne",
"private-groups": "Prywatne grupy", "private-groups": "Grupy prywatne",
"private-groups.help": "Jeśli włączone, dołączenie do grup wymaga zatwierdzenia przez właściciela grupy <em>(domyślnie: włączone)</em>", "private-groups.help": "Jeśli włączone, dołączenie do grupy wymaga zatwierdzenia przez właściciela grupy <em>(domyślnie: włączone)</em>",
"private-groups.warning": "<strong>Uwaga!</strong>Jeśli ta opcja jest wyłączona i masz prywatne grupy, automatycznie stają się one publiczne.", "private-groups.warning": "<strong>Uwaga!</strong> Jeśli ta opcja jest wyłączona i masz prywatne grupy, automatycznie stają się one publiczne.",
"allow-creation": "Zezwalaj na tworzeni grup", "allow-creation": "Zezwalaj na tworzeni grup",
"allow-creation-help": "Jeśli włączone, użytkownicy mogą tworzyć grupy <em>(domyślnie: wyłączone)</em>", "allow-creation-help": "Jeśli włączone, użytkownicy mogą tworzyć grupy <em>(domyślnie: wyłączone)</em>",
"max-name-length": "Maksymalna długość nazwy grupy", "max-name-length": "Maksymalna długość nazwy grupy",

@ -1,6 +1,6 @@
{ {
"handles": "Uchwyty gości", "handles": "Podpisywanie się gości",
"handles.enabled": "Zezwalaj na uchwyty gości", "handles.enabled": "Zezwalaj gościom na podpisywanie się",
"handles.enabled-help": "Ta opcja udostępnia gościom nowe pole, które umożliwia wybranie nazwy, pod którą będą publikowane ich posty. Jeśli wyłączone, będą po prostu nazywani \"Gość\"", "handles.enabled-help": "Ta opcja udostępnia gościom nowe pole, które umożliwia wybranie nazwy, pod którą będą publikowane ich posty. Jeśli wyłączone, będą po prostu nazywani \"Gość\"",
"privileges": "Uprawnienia gości", "privileges": "Uprawnienia gości",
"privileges.can-search": "Zezwalaj gościom na szukanie bez logowania", "privileges.can-search": "Zezwalaj gościom na szukanie bez logowania",

@ -1,11 +1,11 @@
{ {
"sorting": "Sortowanie postów", "sorting": "Sortowanie postów",
"sorting.post-default": "Domyślne sortowanie postów", "sorting.post-default": "Domyślne sortowanie postów",
"sorting.oldest-to-newest": "Najstarsze do Najnowszych", "sorting.oldest-to-newest": "Najstarsze do najnowszych",
"sorting.newest-to-oldest": "Najnowsze do Najstarszych", "sorting.newest-to-oldest": "Najnowsze do najstarszych",
"sorting.most-votes": "Najwięcej głosów", "sorting.most-votes": "Najwięcej głosów",
"sorting.topic-default": "Domyślne sortowanie tematów", "sorting.topic-default": "Domyślne sortowanie tematów",
"restrictions": "Ograniczenia pistania", "restrictions": "Ograniczenia pisania",
"restrictions.post-queue": "Włącz kolejkę postów", "restrictions.post-queue": "Włącz kolejkę postów",
"restrictions.post-queue-help": "Włączenie kolejki postów będzie dodawało posty nowych użytkowników do kolejki w celu zatwierdzenia.", "restrictions.post-queue-help": "Włączenie kolejki postów będzie dodawało posty nowych użytkowników do kolejki w celu zatwierdzenia.",
"restrictions.seconds-between": "Sekund pomiędzy postami", "restrictions.seconds-between": "Sekund pomiędzy postami",
@ -41,7 +41,7 @@
"composer": "Ustawienia okna pisania", "composer": "Ustawienia okna pisania",
"composer-help": "Następujące ustawienia zarządzają funkcjonalnością oraz/lub wyglądem okna pisania postów wyświetlanego\n\t\t\t\tużytkownikom kiedy tworzą nowe tematy lub odpowiadają w istniejących.", "composer-help": "Następujące ustawienia zarządzają funkcjonalnością oraz/lub wyglądem okna pisania postów wyświetlanego\n\t\t\t\tużytkownikom kiedy tworzą nowe tematy lub odpowiadają w istniejących.",
"composer.show-help": "Pokazuj zakładkę \"Pomoc\"", "composer.show-help": "Pokazuj zakładkę \"Pomoc\"",
"composer.enable-plugin-help": "Zezwalaj wtyczką na dodawanie zawartości do zakładki pomocy", "composer.enable-plugin-help": "Zezwalaj wtyczkom na dodawanie zawartości do zakładki pomocy",
"composer.custom-help": "Własny tekst pomocy", "composer.custom-help": "Własny tekst pomocy",
"ip-tracking": "Śledzenie IP", "ip-tracking": "Śledzenie IP",
"ip-tracking.each-post": "Śledź adres IP każdego z postów" "ip-tracking.each-post": "Śledź adres IP każdego z postów"

@ -1,6 +1,6 @@
{ {
"reconnection": "Ustawienia ponownego łączenia", "reconnection": "Ustawienia ponownego łączenia",
"max-attempts": "Maksymalna liczna prób połączenia", "max-attempts": "Maksymalna liczba prób połączenia",
"default-placeholder": "Domyślnie: %1", "default-placeholder": "Domyślnie: %1",
"delay": "Opóźnienie ponownego łączenia" "delay": "Opóźnienie ponownego łączenia"
} }

@ -1,5 +1,5 @@
{ {
"tag": "Ustawienia Tagów", "tag": "Ustawienia tagów",
"min-per-topic": "Minimalna liczba tagów na temat", "min-per-topic": "Minimalna liczba tagów na temat",
"max-per-topic": "Maksymalna liczba tagów na temat", "max-per-topic": "Maksymalna liczba tagów na temat",
"min-length": "Minimalna długość taga", "min-length": "Minimalna długość taga",

@ -1,15 +1,15 @@
{ {
"posts": "Posty", "posts": "Posty",
"allow-files": "Zezwalaj użytkownikom wysyłać pliki", "allow-files": "Zezwalaj użytkownikom wysyłać pliki",
"private": "Rób wysyłane pliki prywatnymi", "private": "Oznaczaj wysyłane pliki jako prywatne",
"max-image-width": "Zmniejszaj obrazy do specyficznej szerokości (w pikselach)", "max-image-width": "Zmniejszaj obrazy do zadanej szerokości (w pikselach)",
"max-image-width-help": "(w pikselach, domyślnie: 760px; ustaw 0, aby wyłączyć)", "max-image-width-help": "(w pikselach, domyślnie: 760px; ustaw 0, aby wyłączyć)",
"max-file-size": "Maksymalny rozmiar plików (w KiB)", "max-file-size": "Maksymalny rozmiar plików (w KiB)",
"max-file-size-help": "(w kilobajtach, domyślnie: 2,048 KiB)", "max-file-size-help": "(w kilobajtach, domyślnie: 2048 KiB)",
"allow-topic-thumbnails": "Zezwalaj użytkownikom na wysyłanie obrazków tematów", "allow-topic-thumbnails": "Zezwalaj użytkownikom na ustawianie miniaturek tematów",
"topic-thumb-size": "Rozmiar miniatury tematu", "topic-thumb-size": "Rozmiar miniatury tematu",
"allowed-file-extensions": "Dozwolone typy plików", "allowed-file-extensions": "Dozwolone typy plików",
"allowed-file-extensions-help": "Tutaj wprowadź oddzielone kropką rozszerzenia plików (np. <code>pdf,xls,doc</code>). Pusta lista oznacza, że wszystkie rozszerzenia są dozwolone.", "allowed-file-extensions-help": "Wprowadź rozdzielone przecinkami rozszerzenia plików (np. <code>pdf,xls,doc</code>). Pusta lista oznacza, że wszystkie rozszerzenia są dozwolone.",
"profile-avatars": "Profilowe awatary", "profile-avatars": "Profilowe awatary",
"allow-profile-image-uploads": "Zezwalaj użytkownikom na ładowanie obrazów profilowych", "allow-profile-image-uploads": "Zezwalaj użytkownikom na ładowanie obrazów profilowych",
"convert-profile-image-png": "Konwertuj przesłane obrazy profilowe na PNG", "convert-profile-image-png": "Konwertuj przesłane obrazy profilowe na PNG",
@ -20,9 +20,9 @@
"max-profile-image-size": "Maksymalny rozmiar obrazka profilowego", "max-profile-image-size": "Maksymalny rozmiar obrazka profilowego",
"max-profile-image-size-help": "(w kilobajtach, domyślnie: 256 KiB)", "max-profile-image-size-help": "(w kilobajtach, domyślnie: 256 KiB)",
"max-cover-image-size": "Maksymalny rozmiar obrazka profilowego", "max-cover-image-size": "Maksymalny rozmiar obrazka profilowego",
"max-cover-image-size-help": "(w kilobajtach, domyślnie: 2,048 KiB)", "max-cover-image-size-help": "(w kilobajtach, domyślnie: 2048 KiB)",
"keep-all-user-images": "Zachowaj stare wersje awatarów oraz okładek profili na serwerze", "keep-all-user-images": "Zachowaj stare wersje awatarów oraz okładek profili na serwerze",
"profile-covers": "Okładki profili", "profile-covers": "Okładki profili",
"default-covers": "Domyślne obrazy profilowe", "default-covers": "Domyślne obrazy profilowe",
"default-covers-help": "Dodaj udzieloną kropkami listę domyślnych obrazów dla kont użytkowników, którzy nie wysłali swoich własnych obrazów profilowych." "default-covers-help": "Dodaj rozdzieloną przecinkami listę domyślnych obrazów dla kont użytkowników, którzy nie wysłali swoich własnych obrazów profilowych."
} }

@ -1,38 +1,38 @@
{ {
"authentication": "Autoryzacja", "authentication": "Uwierzytelnianie",
"allow-local-login": "Zezwalaj na lokalne logowanie", "allow-local-login": "Zezwalaj na lokalne logowanie",
"require-email-confirmation": "Wymagaj potwierdzenia adresu email", "require-email-confirmation": "Wymagaj potwierdzenia adresu email",
"email-confirm-interval": "Użytkownik nie może ponownie wysłać email z potwierdzeniem, dopóki", "email-confirm-interval": "Użytkownik nie może ponownie wysłać email z potwierdzeniem, dopóki nie minie",
"email-confirm-email2": "minut upłynęło", "email-confirm-email2": "minut",
"allow-login-with": "Zezwalaj na logowanie przy użyciu", "allow-login-with": "Zezwalaj na logowanie przy użyciu",
"allow-login-with.username-email": "Nazwy użytkownika lub adresu email", "allow-login-with.username-email": "Nazwy użytkownika lub adresu email",
"allow-login-with.username": "Tylko Nazwy Użytkownia", "allow-login-with.username": "Tylko nazwy użytkownika",
"allow-login-with.email": "Tylko adresu email", "allow-login-with.email": "Tylko adresu email",
"account-settings": "Ustawienia konta", "account-settings": "Ustawienia konta",
"disable-username-changes": "Wyłącz możliwość zmiany nazwy użytkownika", "disable-username-changes": "Wyłącz możliwość zmiany nazwy użytkownika",
"disable-email-changes": "Wyłącz możliwość zmiany adresu email", "disable-email-changes": "Wyłącz możliwość zmiany adresu email",
"disable-password-changes": "Wyłącz możliwość zmiany hasła", "disable-password-changes": "Wyłącz możliwość zmiany hasła",
"allow-account-deletion": "Zezwalaj na usunięcie konta", "allow-account-deletion": "Zezwalaj na usunięcie konta",
"user-info-private": "Ukrywaj listę oraz dane użytkowników przed goścmi", "user-info-private": "Ukrywaj listę oraz dane użytkowników przed gośćmi",
"hide-fullname": "Ukrywaj pełne imię i nazwisko przed innymi użytkownikami", "hide-fullname": "Ukrywaj pełne imię i nazwisko przed innymi użytkownikami",
"hide-email": "Ukryj adresy email użytkowników.", "hide-email": "Ukryj adresy email użytkowników",
"themes": "Style", "themes": "Motywy",
"disable-user-skins": "Uniemożliwić użytkownikom wybranie niestandardowej skórę", "disable-user-skins": "Nie zezwalaj użytkownikom na wybranie niestandardowej skórki",
"account-protection": "Ochrona konta", "account-protection": "Ochrona konta",
"login-attempts": "Prób logowania na godzinę", "login-attempts": "Maksymalna liczba prób logowania na godzinę",
"login-attempts-help": "Jeśli liczba prób logowania na konto użytkownika przekroczy ten próg, to konto zostanie zablokowane na zdefiniowany wcześniej czas", "login-attempts-help": "Jeśli liczba prób logowania na konto użytkownika przekroczy ten próg, to konto zostanie zablokowane na zdefiniowany wcześniej czas",
"lockout-duration": "Czas trwania blokady konta (minuty)", "lockout-duration": "Czas trwania blokady konta (minuty)",
"login-days": "Liczba dni zapamiętywania sesji logowania użytkownika", "login-days": "Liczba dni zapamiętywania sesji logowania użytkownika",
"password-expiry-days": "Wymuś resetowanie hasła po określonej liczbie dni", "password-expiry-days": "Wymuś resetowanie hasła po określonej liczbie dni",
"registration": "Rejestracja Użytkownika", "registration": "Rejestracja użytkownika",
"registration-type": "Typ rejestracji", "registration-type": "Typ rejestracji",
"registration-type.normal": "Normalna", "registration-type.normal": "Standardowa",
"registration-type.admin-approval": "Zatwierdzenie Admina", "registration-type.admin-approval": "Zatwierdzenie administratora",
"registration-type.admin-approval-ip": "Zatwierdzenie Admina dla IP", "registration-type.admin-approval-ip": "Zatwierdzenie administratora dla IP",
"registration-type.invite-only": "Tylko zaproszenia", "registration-type.invite-only": "Tylko zaproszenia",
"registration-type.admin-invite-only": "Tylko zaproszenia Admina", "registration-type.admin-invite-only": "Tylko zaproszenia administratora",
"registration-type.disabled": "Brak rejestracji", "registration-type.disabled": "Brak rejestracji",
"registration-type.help": "Normalna - Użytkownicy mogą się rejestrować na stronie /register.<br/>\nZatwierdzenie Admina - Rejestracja użytkowników trafia do <a href=\"%1/admin/manage/registration\">kolejki zatwierdzeń</a> for administrators.<br/>\nZatwierdzenie Admina dla IP - Normalna dla nowych użytkowników, Zatwierdzenie Admina dla adresów IP, które mają już konta.<br/>\nTylko zaproszenia - Użytkownicy mogą zapraszać innych poprzez stronę <a href=\"%1/users\" target=\"_blank\">users</a>.<br/>\nTylko zaproszenia Admina - Tylko admini mogą zapraszać innych poprzez stronę <a href=\"%1/users\" target=\"_blank\">users</a> oraz <a href=\"%1/admin/manage/users\">admin/manage/users</a>.<br/>\nBrak rejestracji - Brak rejestracji użytkowników.<br/>", "registration-type.help": "Standardowa - Użytkownicy mogą się rejestrować na stronie /register.<br/>\nZatwierdzenie administratora - Rejestracja użytkowników trafia do <a href=\"%1/admin/manage/registration\">kolejki zatwierdzeń</a> administratora.<br/>\nZatwierdzenie administratora dla IP - Standardowa dla nowych użytkowników, Zatwierdzenie administratora dla adresów IP, które mają już konta.<br/>\nTylko zaproszenia - Użytkownicy mogą zapraszać innych poprzez stronę <a href=\"%1/users\" target=\"_blank\">users</a>.<br/>\nTylko zaproszenia administratora - Tylko administratorzy mogą zapraszać innych poprzez stronę <a href=\"%1/users\" target=\"_blank\">users</a> oraz <a href=\"%1/admin/manage/users\">admin/manage/users</a>.<br/>\nBrak rejestracji - Brak rejestracji użytkowników.<br/>",
"registration.max-invites": "Maksymalnie liczba zaproszeń na użytkownika", "registration.max-invites": "Maksymalnie liczba zaproszeń na użytkownika",
"max-invites": "Maksymalnie liczba zaproszeń na użytkownika", "max-invites": "Maksymalnie liczba zaproszeń na użytkownika",
"max-invites-help": "0 dla braku ograniczeń. Administratorzy otrzymują nieskończoną liczbę zaproszeń<br>Aplikowane tylko dla \"Tylko zaproszeni\"", "max-invites-help": "0 dla braku ograniczeń. Administratorzy otrzymują nieskończoną liczbę zaproszeń<br>Aplikowane tylko dla \"Tylko zaproszeni\"",
@ -40,25 +40,25 @@
"invite-expiration-help": "Liczba dni, po których wygasają zaproszenia.", "invite-expiration-help": "Liczba dni, po których wygasają zaproszenia.",
"min-username-length": "Minimalna długość nazwy użytkownika", "min-username-length": "Minimalna długość nazwy użytkownika",
"max-username-length": "Maksymalna długość nazwy użytkownika", "max-username-length": "Maksymalna długość nazwy użytkownika",
"min-password-length": "Maksymalna długość hasła", "min-password-length": "Minimalna długość hasła",
"min-password-strength": "Minimalna długość hasła", "min-password-strength": "Minimalna siła hasła",
"max-about-me-length": "Maksymalna długość pola O mnie", "max-about-me-length": "Maksymalna długość pola O mnie",
"terms-of-use": "Warunki użytkowania forum <small>(Pozostaw puste, aby wyłączyć)</small>", "terms-of-use": "Warunki użytkowania forum <small>(Pozostaw puste, aby wyłączyć)</small>",
"user-search": "Wyszukiwanie użytkownków", "user-search": "Wyszukiwanie użytkownków",
"user-search-results-per-page": "Liczba wyników do wyświetlenia", "user-search-results-per-page": "Liczba wyników do wyświetlenia",
"default-user-settings": "Domyślne ustawienie użytkownia", "default-user-settings": "Domyślne ustawienia użytkownika",
"show-email": "Pokazuj adres email", "show-email": "Pokazuj adres email",
"show-fullname": "Pokazuj imię", "show-fullname": "Pokazuj pełną nazwę uzytkownika",
"restrict-chat": "Pozwalaj tylko wiadomości chat od użytkowników, których śledzę", "restrict-chat": "Pozwalaj na wiadomości chat tylko od użytkowników, których śledzę",
"outgoing-new-tab": "Otwieraj odnośniki wychodzące w nowej karcie", "outgoing-new-tab": "Otwieraj odnośniki wychodzące na nowej karcie",
"topic-search": "Włącz wyszukiwanie wewnątrz tematów", "topic-search": "Włącz wyszukiwanie wewnątrz tematów",
"digest-freq": "Zapisz się do podsumowań", "digest-freq": "Podsumowania - tryb",
"digest-freq.off": "Wyłączone", "digest-freq.off": "Wyłączone",
"digest-freq.daily": "Dzienny ", "digest-freq.daily": "Dzienny ",
"digest-freq.weekly": "Tygodniowy", "digest-freq.weekly": "Tygodniowy",
"digest-freq.monthly": "Miesięczny", "digest-freq.monthly": "Miesięczny",
"email-chat-notifs": "Wyślij e-maila, jeśli dostanę nową wiadomość, a nie jestem on-line", "email-chat-notifs": "Wyślij powiadomienie email, jeśli dostanę nową wiadomość, a nie jestem on-line",
"email-post-notif": "Wyślij email, kiedy w tematach, które subskrybuję, pojawią się odpowiedzi", "email-post-notif": "Wyślij wiadomość email, kiedy w tematach, które subskrybuję, pojawią się odpowiedzi",
"follow-created-topics": "Śledź tematy, które stworzyłeś", "follow-created-topics": "Śledź tematy, które stworzyłeś",
"follow-replied-topics": "Śledź tematy, w których się wypowiedziałeś " "follow-replied-topics": "Śledź tematy, w których się wypowiedziałeś "
} }

@ -5,6 +5,6 @@
"disable-rss-feeds": "Wyłącz kanały RSS", "disable-rss-feeds": "Wyłącz kanały RSS",
"disable-sitemap-xml": "Wyłącz Sitemap.xml", "disable-sitemap-xml": "Wyłącz Sitemap.xml",
"sitemap-topics": "Liczba tematów do wyświetlenia w mapie strony", "sitemap-topics": "Liczba tematów do wyświetlenia w mapie strony",
"clear-sitemap-cache": "Wyczyść pamięć podręczną map strony", "clear-sitemap-cache": "Wyczyść pamięć podręczną mapy strony",
"view-sitemap": "Zobacz mapę strony" "view-sitemap": "Wyświetl mapę strony"
} }

@ -10,11 +10,11 @@
"share_this_category": "Udostępnij tę kategorię", "share_this_category": "Udostępnij tę kategorię",
"watch": "Obserwuj", "watch": "Obserwuj",
"ignore": "Ignoruj", "ignore": "Ignoruj",
"watching": "Obserwowanie", "watching": "Obserwowane",
"ignoring": "Ignorowanie", "ignoring": "Ignorowane",
"watching.description": "Pokazuj tematy jako nieprzeczytane", "watching.description": "Pokazuj tematy w nieprzeczytanych",
"ignoring.description": "Nie pokazuj tematów jako nieprzeczytane", "ignoring.description": "Nie pokazuj tematów w nieprzeczytanych",
"watch.message": "Włączyłeś powiadomienia dla tej kategorii oraz subkategorii.", "watch.message": "Włączyłeś powiadomienia dla tej kategorii oraz wszystkich podkategorii.",
"ignore.message": "Wyłączyłeś powiadomienia dla tej kategorii oraz subkategorii.", "ignore.message": "Wyłączyłeś powiadomienia dla tej kategorii oraz wszystkich podkategorii.",
"watched-categories": "Obserwowane kategorie" "watched-categories": "Obserwowane kategorie"
} }

@ -6,15 +6,15 @@
"greeting_with_name": "Witaj %1", "greeting_with_name": "Witaj %1",
"welcome.text1": "Dziękujemy za rejestrację w %1", "welcome.text1": "Dziękujemy za rejestrację w %1",
"welcome.text2": "Aby aktywować swoje konto, musisz potwierdzić, że skorzystałeś z własnego adresu e-mail.", "welcome.text2": "Aby aktywować swoje konto, musisz potwierdzić, że skorzystałeś z własnego adresu e-mail.",
"welcome.text3": "Administrator zaakceptował twoje podanie o rejestrację. Możesz się zalogować, używając swojej nazwy użytkownika i hasła.", "welcome.text3": "Administrator zaakceptował twój wniosek o rejestrację. Możesz się zalogować, używając swojej nazwy użytkownika i hasła.",
"welcome.cta": "Kliknij tutaj, by potwierdzić swój adres", "welcome.cta": "Kliknij tutaj, aby potwierdzić swój adres",
"invitation.text1": "%1 zaprasza do dołączenia do %2", "invitation.text1": "%1 zaprasza do dołączenia do %2",
"invitation.ctr": "Kliknij tutaj, aby utworzyć konto.", "invitation.ctr": "Kliknij tutaj, aby utworzyć konto.",
"reset.text1": "Otrzymaliśmy żądanie przywrócenia twojego hasła. Jeśli nie żądałeś przywrócenia hasła, zignoruj ten e-mail.", "reset.text1": "Otrzymaliśmy żądanie przywrócenia twojego hasła. Jeśli nie żądałeś przywrócenia hasła, zignoruj ten e-mail.",
"reset.text2": "Aby przywrócić swoje hasło, skorzystaj z poniższego odnośnika:", "reset.text2": "Aby przywrócić swoje hasło, skorzystaj z poniższego odnośnika:",
"reset.cta": "Kliknij tu, by przywrócić swoje hasło", "reset.cta": "Kliknij tu, aby przywrócić swoje hasło",
"reset.notify.subject": "Hasło pomyślnie zmienione", "reset.notify.subject": "Hasło zmienione pomyślnie",
"reset.notify.text1": "Informujemy, że %1, twoje hasło zostało pomyślnie zmienione.", "reset.notify.text1": "Informujemy, że twoje hasło zostało pomyślnie zmienione w %1",
"reset.notify.text2": "Jeśli nie wyraziłeś na to zgody, proszę niezwłocznie poinformować administratora.", "reset.notify.text2": "Jeśli nie wyraziłeś na to zgody, proszę niezwłocznie poinformować administratora.",
"digest.notifications": "Masz nowe powiadomienia od %1:", "digest.notifications": "Masz nowe powiadomienia od %1:",
"digest.latest_topics": "Ostatnie tematy z %1", "digest.latest_topics": "Ostatnie tematy z %1",
@ -24,16 +24,16 @@
"digest.day": "dzień", "digest.day": "dzień",
"digest.week": "tydzień", "digest.week": "tydzień",
"digest.month": "miesiąc", "digest.month": "miesiąc",
"digest.subject": "Digest for %1", "digest.subject": "Podpis %1",
"notif.chat.subject": "Nowa wiadomość czatu od %1", "notif.chat.subject": "Nowa wiadomość czatu od %1",
"notif.chat.cta": "Kliknij tutaj, by kontynuować konwersację", "notif.chat.cta": "Kliknij tutaj, by kontynuować konwersację",
"notif.chat.unsub.info": "To powiadomienie o czacie zostało Ci wysłane zgodnie z ustawieniami twojego konta.", "notif.chat.unsub.info": "To powiadomienie o czacie zostało Ci wysłane zgodnie z ustawieniami twojego konta.",
"notif.post.cta": "Kliknij tutaj, aby przeczytać cały temat.", "notif.post.cta": "Kliknij tutaj, aby przeczytać cały temat.",
"notif.post.unsub.info": "To powiadomienie o poście zostało Ci wysłane zgodnie z ustawieniami twojego konta.", "notif.post.unsub.info": "To powiadomienie o poście zostało Ci wysłane zgodnie z ustawieniami twojego konta.",
"test.text1": "To jest e-mail testowy, aby sprawdzić, czy poprawnie skonfigurowałeś e-mailer w swoim NodeBB.", "test.text1": "To jest e-mail testowy, aby sprawdzić, czy poprawnie skonfigurowałeś e-mailer w swoim NodeBB.",
"unsub.cta": "Kliknij tutaj, by zmienić te ustawienia", "unsub.cta": "Kliknij tutaj, aby zmienić te ustawienia",
"banned.subject": "Zostałeś zbanowany przez %1", "banned.subject": "Zostałeś zbanowany na %1",
"banned.text1": "Użytkownik %1 został zbanowany przez %2.", "banned.text1": "Użytkownik %1 został zbanowany na %2.",
"banned.text2": "Ban potrwa do %1", "banned.text2": "Ban potrwa do %1",
"banned.text3": "To jest powód, dla którego zostałeś zbanowany:", "banned.text3": "To jest powód, dla którego zostałeś zbanowany:",
"closing": "Dziękujemy!" "closing": "Dziękujemy!"

@ -72,11 +72,11 @@
"guest_posted_ago": "Gość napisał %1", "guest_posted_ago": "Gość napisał %1",
"last_edited_by": "ostatnio edytowany przez %1", "last_edited_by": "ostatnio edytowany przez %1",
"norecentposts": "Brak ostatnich postów", "norecentposts": "Brak ostatnich postów",
"norecenttopics": "Brak Ostatnich tematów", "norecenttopics": "Brak ostatnich tematów",
"recentposts": "Ostatnie posty", "recentposts": "Ostatnie posty",
"recentips": "Adresy IP ostatnich logowań", "recentips": "Adresy IP ostatnich logowań",
"moderator_tools": "Narzędzia dla moderatorów", "moderator_tools": "Narzędzia dla moderatorów",
"away": "Z dala", "away": "Zaraz wracam",
"dnd": "Nie przeszkadzać", "dnd": "Nie przeszkadzać",
"invisible": "Niewidoczny", "invisible": "Niewidoczny",
"offline": "Niedostępny", "offline": "Niedostępny",
@ -101,7 +101,7 @@
"reconnecting-message": "Wygląda na to, że twoje połączenie z %1 zostało przerwane. Proszę czekać, gdy staramy się je odnowić.", "reconnecting-message": "Wygląda na to, że twoje połączenie z %1 zostało przerwane. Proszę czekać, gdy staramy się je odnowić.",
"play": "Odtwórz", "play": "Odtwórz",
"cookies.message": "Ta strona używa plików cookies, by zapewnić Ci najlepsze działanie naszej strony.", "cookies.message": "Ta strona używa plików cookies, by zapewnić Ci najlepsze działanie naszej strony.",
"cookies.accept": "Mam to!", "cookies.accept": "Rozumiem!",
"cookies.learn_more": "Dowiedz się więcej", "cookies.learn_more": "Dowiedz się więcej",
"edited": "Edytowany", "edited": "Edytowany",
"disabled": "Wyłączony", "disabled": "Wyłączony",

@ -12,7 +12,7 @@
"reply-count": "Liczba odpowiedzi", "reply-count": "Liczba odpowiedzi",
"at-least": "Przynajmniej", "at-least": "Przynajmniej",
"at-most": "Co najwyżej", "at-most": "Co najwyżej",
"relevance": "Stosowność", "relevance": "Trafność",
"post-time": "Napisano", "post-time": "Napisano",
"newer-than": "Nowsze niż", "newer-than": "Nowsze niż",
"older-than": "Starsze niż", "older-than": "Starsze niż",

@ -4,7 +4,7 @@
"topic_id_placeholder": "Podaj identyfikator tematu", "topic_id_placeholder": "Podaj identyfikator tematu",
"no_topics_found": "Nie znaleziono żadnych tematów!", "no_topics_found": "Nie znaleziono żadnych tematów!",
"no_posts_found": "Nie znaleziono żadnych postów.", "no_posts_found": "Nie znaleziono żadnych postów.",
"post_is_deleted": "Ten post jest usunięty", "post_is_deleted": "Ten post jest usunięty!",
"topic_is_deleted": "Ten temat jest usunięty!", "topic_is_deleted": "Ten temat jest usunięty!",
"profile": "Profil", "profile": "Profil",
"posted_by": "Napisane przez %1", "posted_by": "Napisane przez %1",
@ -17,7 +17,7 @@
"one_reply_to_this_post": "1 Odpowiedź", "one_reply_to_this_post": "1 Odpowiedź",
"last_reply_time": "Ostatnia odpowiedź", "last_reply_time": "Ostatnia odpowiedź",
"reply-as-topic": "Odpowiedz na temat", "reply-as-topic": "Odpowiedz na temat",
"guest-login-reply": "Zaloguj się, aby odpowiedzieć.", "guest-login-reply": "Zaloguj się, aby odpowiedzieć",
"edit": "Edytuj", "edit": "Edytuj",
"delete": "Usuń", "delete": "Usuń",
"purge": "Wymaż", "purge": "Wymaż",

@ -4,13 +4,13 @@
"username": "Nazwa użytkownika", "username": "Nazwa użytkownika",
"joindate": "Data rejestracji", "joindate": "Data rejestracji",
"postcount": "Liczba postów", "postcount": "Liczba postów",
"email": "Adres e-mail", "email": "Adres email",
"confirm_email": "Potwierdź e-mail", "confirm_email": "Potwierdź email",
"account_info": "Informacje o koncie", "account_info": "Informacje o koncie",
"ban_account": "Zbanuj Konto", "ban_account": "Zbanuj konto",
"ban_account_confirm": "Na pewno chcesz zbanować tego użytkownika?", "ban_account_confirm": "Na pewno chcesz zbanować tego użytkownika?",
"unban_account": "Odbanuj Konto", "unban_account": "Odbanuj konto",
"delete_account": "Skasuj konto", "delete_account": "Usuń konto",
"delete_account_confirm": "Jesteś pewny, że chcesz skasować swoje konto? <br /><strong>Tej operacji nie można cofnąć i utracisz wszystkie swoje dane</strong><br/><br/>Podaj swoją nazwę użytkownika, by potwierdzić skasowanie konta.", "delete_account_confirm": "Jesteś pewny, że chcesz skasować swoje konto? <br /><strong>Tej operacji nie można cofnąć i utracisz wszystkie swoje dane</strong><br/><br/>Podaj swoją nazwę użytkownika, by potwierdzić skasowanie konta.",
"delete_this_account_confirm": "Na pewno chcesz usunąć to konto? <br /><strong>Tej operacji nie można cofnąć i nie będzie możliwości odzyskania swoich danych</strong><br /><br />", "delete_this_account_confirm": "Na pewno chcesz usunąć to konto? <br /><strong>Tej operacji nie można cofnąć i nie będzie możliwości odzyskania swoich danych</strong><br /><br />",
"account-deleted": "Konto usunięte", "account-deleted": "Konto usunięte",
@ -92,7 +92,7 @@
"email_hidden": "Adres e-mail ukryty", "email_hidden": "Adres e-mail ukryty",
"hidden": "ukryty", "hidden": "ukryty",
"paginate_description": "Dziel tematy i posty na strony zamiast używać nieskończonego przewijania", "paginate_description": "Dziel tematy i posty na strony zamiast używać nieskończonego przewijania",
"topics_per_page": "Tematów na Stronę", "topics_per_page": "Tematów na stronę",
"posts_per_page": "Postów na stronę", "posts_per_page": "Postów na stronę",
"notification_sounds": "Odtwarzaj dźwięk, gdy otrzymujesz powiadomienie", "notification_sounds": "Odtwarzaj dźwięk, gdy otrzymujesz powiadomienie",
"notifications_and_sounds": "Powiadomienia i dźwięki", "notifications_and_sounds": "Powiadomienia i dźwięki",
@ -111,7 +111,7 @@
"follow_topics_you_create": "Obserwuj tematy, które utworzyłeś", "follow_topics_you_create": "Obserwuj tematy, które utworzyłeś",
"grouptitle": "Tytuł grupy", "grouptitle": "Tytuł grupy",
"no-group-title": "Brak tytułu grupy", "no-group-title": "Brak tytułu grupy",
"select-skin": "Wybierz Skórkę", "select-skin": "Wybierz skórkę",
"select-homepage": "Wybierz stronę startową", "select-homepage": "Wybierz stronę startową",
"homepage": "Strona startowa", "homepage": "Strona startowa",
"homepage_description": "Wybierz stronę, jaką chcesz mieć ustawioną na domyślną, lub \"None\", jeśli chcesz używać domyślnej. ", "homepage_description": "Wybierz stronę, jaką chcesz mieć ustawioną na domyślną, lub \"None\", jeśli chcesz używać domyślnej. ",
@ -129,8 +129,8 @@
"info.banned-reason-label": "Powód", "info.banned-reason-label": "Powód",
"info.banned-no-reason": "Nie podano powodu.", "info.banned-no-reason": "Nie podano powodu.",
"info.username-history": "Historia nazwy użytkownika", "info.username-history": "Historia nazwy użytkownika",
"info.email-history": "Historia adresu e-mail", "info.email-history": "Historia adresu email",
"info.moderation-note": "Notka moderatora", "info.moderation-note": "Notatka moderatora",
"info.moderation-note.success": "Notka nie została zapisana", "info.moderation-note.success": "Notatka została zapisana",
"info.moderation-note.add": "Dodaj notatkę" "info.moderation-note.add": "Dodaj notatkę"
} }

@ -15,10 +15,10 @@
"smtp-transport.gmail-warning2": "有关此解决方法的更多信息,请参阅有关该问题的<a href=\"https://nodemailer.com/usage/using-gmail/\">NodeMailer 文章</a>。 另一种方法是利用 SendGridMailgun 等第三方电子邮件插件。<a href=\"{config.relative_path}/admin/extend/plugins\">点这儿以浏览可用的插件。</a>", "smtp-transport.gmail-warning2": "有关此解决方法的更多信息,请参阅有关该问题的<a href=\"https://nodemailer.com/usage/using-gmail/\">NodeMailer 文章</a>。 另一种方法是利用 SendGridMailgun 等第三方电子邮件插件。<a href=\"{config.relative_path}/admin/extend/plugins\">点这儿以浏览可用的插件。</a>",
"smtp-transport.host": "SMTP 主机名", "smtp-transport.host": "SMTP 主机名",
"smtp-transport.port": "SMTP 端口", "smtp-transport.port": "SMTP 端口",
"smtp-transport.security": "Connection security", "smtp-transport.security": "连接安全设置",
"smtp-transport.security-encrypted": "Encrypted", "smtp-transport.security-encrypted": "加密的",
"smtp-transport.security-starttls": "StartTLS", "smtp-transport.security-starttls": "StartTLS",
"smtp-transport.security-none": "None", "smtp-transport.security-none": "",
"smtp-transport.username": "用户名", "smtp-transport.username": "用户名",
"smtp-transport.username-help": "<b>对于Gmail服务</b>请在这里输入完整的电子邮箱地址,尤其是如果您使用的是 Google Apps 托管的域名。", "smtp-transport.username-help": "<b>对于Gmail服务</b>请在这里输入完整的电子邮箱地址,尤其是如果您使用的是 Google Apps 托管的域名。",
"smtp-transport.password": "密码", "smtp-transport.password": "密码",

@ -46,20 +46,20 @@
"no-privileges": "您没有权限执行此操作。", "no-privileges": "您没有权限执行此操作。",
"category-disabled": "版块已禁用", "category-disabled": "版块已禁用",
"topic-locked": "主题已锁定", "topic-locked": "主题已锁定",
"post-edit-duration-expired": "您必须在发表 %1 秒后才能修改内容", "post-edit-duration-expired": "您只能在发表后 %1 秒内修改内容",
"post-edit-duration-expired-minutes": "在发表 %1 分钟后才能修改内容", "post-edit-duration-expired-minutes": "您只能在发表后 %1 分钟内修改内容",
"post-edit-duration-expired-minutes-seconds": "发表 %1 分 %2 秒后才能修改内容", "post-edit-duration-expired-minutes-seconds": "您只能在发表后 %1 分 %2 秒内修改内容",
"post-edit-duration-expired-hours": "发表 %1 小时后才能修改内容", "post-edit-duration-expired-hours": "您只能在发表后 %1 小时后内修改内容",
"post-edit-duration-expired-hours-minutes": "发表 %1 小时 2 分钟后才能修改内容", "post-edit-duration-expired-hours-minutes": "您只能在发表后 %1 小时 2 分钟内修改内容",
"post-edit-duration-expired-days": "发表 %1 天后才能修改内容", "post-edit-duration-expired-days": "您只能在发表后 %1 天内修改内容",
"post-edit-duration-expired-days-hours": "发表 %1 天 %2 小时后才能修改内容", "post-edit-duration-expired-days-hours": "您只能在发表后 %1 天 %2 小时内修改内容",
"post-delete-duration-expired": "您只能在发表 %1 秒后删除帖子", "post-delete-duration-expired": "您只能在发表后 %1 秒内删除帖子",
"post-delete-duration-expired-minutes": "您只能在发表 %1 分钟后删除帖子", "post-delete-duration-expired-minutes": "您只能在发表后 %1 分钟内删除帖子",
"post-delete-duration-expired-minutes-seconds": "您只能在发表 %1 分 %2 秒后删除帖子", "post-delete-duration-expired-minutes-seconds": "您只能在发表发 %1 分 %2 秒内删除帖子",
"post-delete-duration-expired-hours": "您只能在发表 %1 小时后删除帖子", "post-delete-duration-expired-hours": "您只能在发表后 %1 小时内删除帖子",
"post-delete-duration-expired-hours-minutes": "您只能在发表 %1 小时 %2 分钟后删除帖子", "post-delete-duration-expired-hours-minutes": "您只能在发表后 %1 小时 %2 分钟内删除帖子",
"post-delete-duration-expired-days": "您只能在发表 %1 天后删除帖子", "post-delete-duration-expired-days": "您只能在发表后 %1 天内删除帖子",
"post-delete-duration-expired-days-hours": "您只能在发表 %1 天 %2 小时后删除帖子", "post-delete-duration-expired-days-hours": "您只能在发表后 %1 天 %2 小时内删除帖子",
"cant-delete-topic-has-reply": "您不能删除您的主题,因为已有回复。", "cant-delete-topic-has-reply": "您不能删除您的主题,因为已有回复。",
"cant-delete-topic-has-replies": "您不能删除您的主题,因为已有 %1 条回复。", "cant-delete-topic-has-replies": "您不能删除您的主题,因为已有 %1 条回复。",
"content-too-short": "请增添发帖内容,不能少于 %1 个字符。", "content-too-short": "请增添发帖内容,不能少于 %1 个字符。",

@ -5,7 +5,7 @@ var cacheController = module.exports;
cacheController.get = function (req, res) { cacheController.get = function (req, res) {
var postCache = require('../../posts/cache'); var postCache = require('../../posts/cache');
var groupCache = require('../../groups').cache; var groupCache = require('../../groups').cache;
var userSettingsCache = require('../../user').settingsCache; var objectCache = require('../../database').objectCache;
var avgPostSize = 0; var avgPostSize = 0;
var percentFull = 0; var percentFull = 0;
@ -14,7 +14,7 @@ cacheController.get = function (req, res) {
percentFull = ((postCache.length / postCache.max) * 100).toFixed(2); percentFull = ((postCache.length / postCache.max) * 100).toFixed(2);
} }
res.render('admin/advanced/cache', { var data = {
postCache: { postCache: {
length: postCache.length, length: postCache.length,
max: postCache.max, max: postCache.max,
@ -22,12 +22,6 @@ cacheController.get = function (req, res) {
percentFull: percentFull, percentFull: percentFull,
avgPostSize: avgPostSize, avgPostSize: avgPostSize,
}, },
userSettingsCache: {
length: userSettingsCache.length,
max: userSettingsCache.max,
itemCount: userSettingsCache.itemCount,
percentFull: ((userSettingsCache.length / userSettingsCache.max) * 100).toFixed(2),
},
groupCache: { groupCache: {
length: groupCache.length, length: groupCache.length,
max: groupCache.max, max: groupCache.max,
@ -35,5 +29,17 @@ cacheController.get = function (req, res) {
percentFull: ((groupCache.length / groupCache.max) * 100).toFixed(2), percentFull: ((groupCache.length / groupCache.max) * 100).toFixed(2),
dump: req.query.debug ? JSON.stringify(groupCache.dump(), null, 4) : false, dump: req.query.debug ? JSON.stringify(groupCache.dump(), null, 4) : false,
}, },
}); };
if (objectCache) {
data.objectCache = {
length: objectCache.length,
max: objectCache.max,
itemCount: objectCache.itemCount,
percentFull: ((objectCache.length / objectCache.max) * 100).toFixed(2),
dump: req.query.debug ? JSON.stringify(objectCache.dump(), null, 4) : false,
};
}
res.render('admin/advanced/cache', data);
}; };

@ -37,6 +37,9 @@ uploadsController.upload = function (req, res, filesIterator) {
uploadsController.uploadPost = function (req, res, next) { uploadsController.uploadPost = function (req, res, next) {
uploadsController.upload(req, res, function (uploadedFile, next) { uploadsController.upload(req, res, function (uploadedFile, next) {
if (!parseInt(req.body.cid, 10)) {
return next(new Error('[[error:category-not-selected]]'));
}
var isImage = uploadedFile.type.match(/image./); var isImage = uploadedFile.type.match(/image./);
if (isImage) { if (isImage) {
uploadAsImage(req, uploadedFile, next); uploadAsImage(req, uploadedFile, next);

@ -8,37 +8,52 @@ var nconf = require('nconf');
var session = require('express-session'); var session = require('express-session');
var _ = require('lodash'); var _ = require('lodash');
var semver = require('semver'); var semver = require('semver');
var prompt = require('prompt');
var db; var db;
var mongoModule = module.exports; var mongoModule = module.exports;
function isUriNotSpecified() {
return !prompt.history('mongo:uri').value;
}
mongoModule.questions = [ mongoModule.questions = [
{
name: 'mongo:uri',
description: 'MongoDB connection URI: (leave blank if you wish to specify host, port, username/password and database individually)\nFormat: mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]',
default: nconf.get('mongo:uri') || '',
},
{ {
name: 'mongo:host', name: 'mongo:host',
description: 'Host IP or address of your MongoDB instance', description: 'Host IP or address of your MongoDB instance',
default: nconf.get('mongo:host') || '127.0.0.1', default: nconf.get('mongo:host') || '127.0.0.1',
ask: isUriNotSpecified,
}, },
{ {
name: 'mongo:port', name: 'mongo:port',
description: 'Host port of your MongoDB instance', description: 'Host port of your MongoDB instance',
default: nconf.get('mongo:port') || 27017, default: nconf.get('mongo:port') || 27017,
ask: isUriNotSpecified,
}, },
{ {
name: 'mongo:username', name: 'mongo:username',
description: 'MongoDB username', description: 'MongoDB username',
default: nconf.get('mongo:username') || '', default: nconf.get('mongo:username') || '',
ask: isUriNotSpecified,
}, },
{ {
name: 'mongo:password', name: 'mongo:password',
description: 'Password of your MongoDB database', description: 'Password of your MongoDB database',
hidden: true,
default: nconf.get('mongo:password') || '', default: nconf.get('mongo:password') || '',
hidden: true,
ask: isUriNotSpecified,
before: function (value) { value = value || nconf.get('mongo:password') || ''; return value; }, before: function (value) { value = value || nconf.get('mongo:password') || ''; return value; },
}, },
{ {
name: 'mongo:database', name: 'mongo:database',
description: 'MongoDB database name', description: 'MongoDB database name',
default: nconf.get('mongo:database') || 'nodebb', default: nconf.get('mongo:database') || 'nodebb',
ask: isUriNotSpecified,
}, },
]; ];

@ -3,6 +3,36 @@
module.exports = function (db, module) { module.exports = function (db, module) {
var helpers = module.helpers.mongo; var helpers = module.helpers.mongo;
var LRU = require('lru-cache');
var _ = require('lodash');
var pubsub = require('../../pubsub');
var cache = LRU({
max: 10000,
length: function () { return 1; },
maxAge: 0,
});
module.objectCache = cache;
pubsub.on('mongo:hash:cache:del', function (key) {
cache.del(key);
});
pubsub.on('mongo:hash:cache:reset', function () {
cache.reset();
});
module.delObjectCache = function (key) {
pubsub.publish('mongo:hash:cache:del', key);
cache.del(key);
};
module.resetObjectCache = function () {
pubsub.publish('mongo:hash:cache:reset');
cache.reset();
};
module.setObject = function (key, data, callback) { module.setObject = function (key, data, callback) {
callback = callback || helpers.noop; callback = callback || helpers.noop;
if (!key || !data) { if (!key || !data) {
@ -12,7 +42,11 @@ module.exports = function (db, module) {
delete data['']; delete data[''];
} }
db.collection('objects').update({ _key: key }, { $set: data }, { upsert: true, w: 1 }, function (err) { db.collection('objects').update({ _key: key }, { $set: data }, { upsert: true, w: 1 }, function (err) {
callback(err); if (err) {
return callback(err);
}
module.delObjectCache(key);
callback();
}); });
}; };
@ -31,26 +65,48 @@ module.exports = function (db, module) {
if (!key) { if (!key) {
return callback(); return callback();
} }
db.collection('objects').findOne({ _key: key }, { _id: 0, _key: 0 }, callback);
module.getObjects([key], function (err, data) {
if (err) {
return callback(err);
}
callback(null, data && data.length ? data[0] : null);
});
}; };
module.getObjects = function (keys, callback) { module.getObjects = function (keys, callback) {
function getFromCache(next) {
setImmediate(next, null, keys.map(function (key) {
return _.clone(cache.get(key));
}));
}
if (!Array.isArray(keys) || !keys.length) { if (!Array.isArray(keys) || !keys.length) {
return callback(null, []); return callback(null, []);
} }
db.collection('objects').find({ _key: { $in: keys } }, { _id: 0 }).toArray(function (err, data) {
var nonCachedKeys = keys.filter(function (key) {
return !cache.get(key);
});
if (!nonCachedKeys.length) {
return getFromCache(callback);
}
db.collection('objects').find({ _key: { $in: nonCachedKeys } }, { _id: 0 }).toArray(function (err, data) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
var map = helpers.toMap(data); data.forEach(function (objectData) {
var returnData = []; if (objectData) {
var key = objectData._key;
for (var i = 0; i < keys.length; i += 1) { delete objectData._key;
returnData.push(map[keys[i]]); cache.set(key, objectData);
} }
});
callback(null, returnData); getFromCache(callback);
}); });
}; };
@ -58,16 +114,10 @@ module.exports = function (db, module) {
if (!key) { if (!key) {
return callback(); return callback();
} }
field = helpers.fieldToString(field); module.getObject(key, function (err, item) {
var _fields = {
_id: 0,
};
_fields[field] = 1;
db.collection('objects').findOne({ _key: key }, { fields: _fields }, function (err, item) {
if (err || !item) { if (err || !item) {
return callback(err, null); return callback(err, null);
} }
callback(null, item.hasOwnProperty(field) ? item[field] : null); callback(null, item.hasOwnProperty(field) ? item[field] : null);
}); });
}; };
@ -76,22 +126,13 @@ module.exports = function (db, module) {
if (!key) { if (!key) {
return callback(); return callback();
} }
var _fields = { module.getObject(key, function (err, item) {
_id: 0,
};
var i;
for (i = 0; i < fields.length; i += 1) {
fields[i] = helpers.fieldToString(fields[i]);
_fields[fields[i]] = 1;
}
db.collection('objects').findOne({ _key: key }, { fields: _fields }, function (err, item) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
item = item || {}; item = item || {};
var result = {}; var result = {};
for (i = 0; i < fields.length; i += 1) { for (var i = 0; i < fields.length; i += 1) {
result[fields[i]] = item[fields[i]] !== undefined ? item[fields[i]] : null; result[fields[i]] = item[fields[i]] !== undefined ? item[fields[i]] : null;
} }
callback(null, result); callback(null, result);
@ -102,38 +143,24 @@ module.exports = function (db, module) {
if (!Array.isArray(keys) || !keys.length) { if (!Array.isArray(keys) || !keys.length) {
return callback(null, []); return callback(null, []);
} }
var _fields = { module.getObjects(keys, function (err, items) {
_id: 0,
_key: 1,
};
for (var i = 0; i < fields.length; i += 1) {
fields[i] = helpers.fieldToString(fields[i]);
_fields[fields[i]] = 1;
}
db.collection('objects').find({ _key: { $in: keys } }, { fields: _fields }).toArray(function (err, items) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
if (items === null) { if (items === null) {
items = []; items = [];
} }
var map = helpers.toMap(items);
var returnData = []; var returnData = [];
var item; var item;
var result;
for (var i = 0; i < keys.length; i += 1) { for (var i = 0; i < keys.length; i += 1) {
item = map[keys[i]] || {}; item = items[i] || {};
result = {};
for (var k = 0; k < fields.length; k += 1) { for (var k = 0; k < fields.length; k += 1) {
if (item[fields[k]] === undefined) { result[fields[k]] = item[fields[k]] !== undefined ? item[fields[k]] : null;
item[fields[k]] = null;
}
} }
returnData.push(item); returnData.push(result);
} }
callback(null, returnData); callback(null, returnData);
@ -220,7 +247,11 @@ module.exports = function (db, module) {
}); });
db.collection('objects').update({ _key: key }, { $unset: data }, function (err) { db.collection('objects').update({ _key: key }, { $unset: data }, function (err) {
callback(err); if (err) {
return callback(err);
}
module.delObjectCache(key);
callback();
}); });
}; };
@ -244,7 +275,11 @@ module.exports = function (db, module) {
data[field] = value; data[field] = value;
db.collection('objects').findAndModify({ _key: key }, {}, { $inc: data }, { new: true, upsert: true }, function (err, result) { db.collection('objects').findAndModify({ _key: key }, {}, { $inc: data }, { new: true, upsert: true }, function (err, result) {
callback(err, result && result.value ? result.value[field] : null); if (err) {
return callback(err);
}
module.delObjectCache(key);
callback(null, result && result.value ? result.value[field] : null);
}); });
}; };
}; };

@ -13,7 +13,11 @@ module.exports = function (db, module) {
module.emptydb = function (callback) { module.emptydb = function (callback) {
callback = callback || helpers.noop; callback = callback || helpers.noop;
db.collection('objects').remove({}, function (err) { db.collection('objects').remove({}, function (err) {
callback(err); if (err) {
return callback(err);
}
module.resetObjectCache();
callback();
}); });
}; };
@ -32,7 +36,11 @@ module.exports = function (db, module) {
return callback(); return callback();
} }
db.collection('objects').remove({ _key: key }, function (err) { db.collection('objects').remove({ _key: key }, function (err) {
callback(err); if (err) {
return callback(err);
}
module.delObjectCache(key);
callback();
}); });
}; };
@ -42,7 +50,15 @@ module.exports = function (db, module) {
return callback(); return callback();
} }
db.collection('objects').remove({ _key: { $in: keys } }, function (err) { db.collection('objects').remove({ _key: { $in: keys } }, function (err) {
callback(err); if (err) {
return callback(err);
}
keys.forEach(function (key) {
module.delObjectCache(key);
});
callback(null);
}); });
}; };
@ -75,7 +91,34 @@ module.exports = function (db, module) {
module.rename = function (oldKey, newKey, callback) { module.rename = function (oldKey, newKey, callback) {
callback = callback || helpers.noop; callback = callback || helpers.noop;
db.collection('objects').update({ _key: oldKey }, { $set: { _key: newKey } }, { multi: true }, function (err) { db.collection('objects').update({ _key: oldKey }, { $set: { _key: newKey } }, { multi: true }, function (err) {
callback(err); if (err) {
return callback(err);
}
module.delObjectCache(oldKey);
module.delObjectCache(newKey);
callback();
});
};
module.type = function (key, callback) {
db.collection('objects').findOne({ _key: key }, function (err, data) {
if (err) {
return callback(err);
}
if (!data) {
return callback(null, null);
}
var keys = Object.keys(data);
if (keys.length === 4 && data.hasOwnProperty('_key') && data.hasOwnProperty('score') && data.hasOwnProperty('value')) {
return callback(null, 'zset');
} else if (keys.length === 3 && data.hasOwnProperty('_key') && data.hasOwnProperty('members')) {
return callback(null, 'set');
} else if (keys.length === 3 && data.hasOwnProperty('_key') && data.hasOwnProperty('array')) {
return callback(null, 'list');
} else if (keys.length === 3 && data.hasOwnProperty('_key') && data.hasOwnProperty('value')) {
return callback(null, 'string');
}
callback(null, 'hash');
}); });
}; };

@ -137,13 +137,13 @@ module.exports = function (db, module) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
var map = {};
result = result.map(function (item) { result.forEach(function (item) {
return item._key; map[item._key] = true;
}); });
result = sets.map(function (set) { result = sets.map(function (set) {
return result.indexOf(set) !== -1; return !!map[set];
}); });
callback(null, result); callback(null, result);

@ -60,6 +60,12 @@ module.exports = function (redisClient, module) {
}); });
}; };
module.type = function (key, callback) {
redisClient.type(key, function (err, type) {
callback(err, type !== 'none' ? type : null);
});
};
module.expire = function (key, seconds, callback) { module.expire = function (key, seconds, callback) {
callback = callback || function () {}; callback = callback || function () {};
redisClient.expire(key, seconds, function (err) { redisClient.expire(key, seconds, function (err) {

@ -15,7 +15,7 @@ var LRU = require('lru-cache');
var cache = LRU({ var cache = LRU({
max: 40000, max: 40000,
maxAge: 1000 * 60 * 60, maxAge: 0,
}); });
module.exports = function (Groups) { module.exports = function (Groups) {
@ -382,7 +382,7 @@ module.exports = function (Groups) {
} }
var nonCachedUids = uids.filter(function (uid) { var nonCachedUids = uids.filter(function (uid) {
return !cache.has(uid + ':' + groupName); return !cache.get(uid + ':' + groupName);
}); });
if (!nonCachedUids.length) { if (!nonCachedUids.length) {
@ -415,7 +415,7 @@ module.exports = function (Groups) {
} }
var nonCachedGroups = groups.filter(function (groupName) { var nonCachedGroups = groups.filter(function (groupName) {
return !cache.has(uid + ':' + groupName); return !cache.get(uid + ':' + groupName);
}); });
if (!nonCachedGroups.length) { if (!nonCachedGroups.length) {

@ -44,8 +44,8 @@ Blacklist.save = function (rules, callback) {
db.setObject('ip-blacklist-rules', { rules: rules }, next); db.setObject('ip-blacklist-rules', { rules: rules }, next);
}, },
function (next) { function (next) {
Blacklist.load(next);
pubsub.publish('blacklist:reload'); pubsub.publish('blacklist:reload');
setImmediate(next);
}, },
], callback); ], callback);
}; };

@ -6,7 +6,7 @@ var meta = require('../meta');
var cache = LRU({ var cache = LRU({
max: parseInt(meta.config.postCacheSize, 10) || 1048576, max: parseInt(meta.config.postCacheSize, 10) || 1048576,
length: function (n) { return n.length; }, length: function (n) { return n.length; },
maxAge: 1000 * 60 * 60, maxAge: 0,
}); });
module.exports = cache; module.exports = cache;

@ -170,6 +170,9 @@ module.exports = function (app, middleware, hotswapIds, callback) {
res.redirect(relativePath + '/assets/uploads' + req.path + '?' + meta.config['cache-buster']); res.redirect(relativePath + '/assets/uploads' + req.path + '?' + meta.config['cache-buster']);
}); });
// only warn once
var warned = new Set();
// DEPRECATED // DEPRECATED
var deprecatedPaths = [ var deprecatedPaths = [
'/nodebb.min.js', '/nodebb.min.js',
@ -188,8 +191,11 @@ module.exports = function (app, middleware, hotswapIds, callback) {
]; ];
app.use(relativePath, function (req, res, next) { app.use(relativePath, function (req, res, next) {
if (deprecatedPaths.some(function (path) { return req.path.startsWith(path); })) { if (deprecatedPaths.some(function (path) { return req.path.startsWith(path); })) {
winston.verbose('[deprecated] Accessing `' + req.path.slice(1) + '` from `/` is deprecated. ' + if (!warned.has(req.path)) {
winston.warn('[deprecated] Accessing `' + req.path.slice(1) + '` from `/` is deprecated to be REMOVED in NodeBB v1.7.0. ' +
'Use `/assets' + req.path + '` to access this file.'); 'Use `/assets' + req.path + '` to access this file.');
warned.add(req.path);
}
res.redirect(relativePath + '/assets' + req.path + '?' + meta.config['cache-buster']); res.redirect(relativePath + '/assets' + req.path + '?' + meta.config['cache-buster']);
} else { } else {
next(); next();
@ -197,8 +203,11 @@ module.exports = function (app, middleware, hotswapIds, callback) {
}); });
// DEPRECATED // DEPRECATED
app.use(relativePath + '/api/language', function (req, res) { app.use(relativePath + '/api/language', function (req, res) {
winston.verbose('[deprecated] Accessing language files from `/api/language` is deprecated. ' + if (!warned.has(req.path)) {
winston.warn('[deprecated] Accessing language files from `/api/language` is deprecated to be REMOVED in NodeBB v1.7.0. ' +
'Use `/assets/language' + req.path + '.json` for prefetch paths.'); 'Use `/assets/language' + req.path + '.json` for prefetch paths.');
warned.add(req.path);
}
res.redirect(relativePath + '/assets/language' + req.path + '.json?' + meta.config['cache-buster']); res.redirect(relativePath + '/assets/language' + req.path + '.json?' + meta.config['cache-buster']);
}); });

@ -4,6 +4,7 @@ var async = require('async');
var path = require('path'); var path = require('path');
var semver = require('semver'); var semver = require('semver');
var readline = require('readline'); var readline = require('readline');
var winston = require('winston');
var db = require('./database'); var db = require('./database');
var file = require('../src/file'); var file = require('../src/file');
@ -35,6 +36,37 @@ Upgrade.getAll = function (callback) {
return semver.compare(versionA, versionB); return semver.compare(versionA, versionB);
})); }));
}, },
async.apply(Upgrade.appendPluginScripts),
], callback);
};
Upgrade.appendPluginScripts = function (files, callback) {
async.waterfall([
// Find all active plugins
async.apply(db.getSortedSetRange.bind(db), 'plugins:active', 0, -1),
// Read plugin.json and check for upgrade scripts
function (plugins, next) {
async.each(plugins, function (plugin, next) {
var configPath = path.join(__dirname, '../node_modules', plugin, 'plugin.json');
try {
var pluginConfig = require(configPath);
if (pluginConfig.hasOwnProperty('upgrades') && Array.isArray(pluginConfig.upgrades)) {
pluginConfig.upgrades.forEach(function (script) {
files.push(path.join(path.dirname(configPath), script));
});
}
next();
} catch (e) {
winston.warn('[upgrade/appendPluginScripts] Unable to read plugin.json for plugin `' + plugin + '`. Skipping.');
process.nextTick(next);
}
}, function (err) {
// Return list of upgrade scripts for continued processing
next(err, files);
});
},
], callback); ], callback);
}; };

@ -2,38 +2,17 @@
'use strict'; 'use strict';
var async = require('async'); var async = require('async');
var _ = require('lodash');
var meta = require('../meta'); var meta = require('../meta');
var db = require('../database'); var db = require('../database');
var plugins = require('../plugins'); var plugins = require('../plugins');
var pubsub = require('../pubsub');
var LRU = require('lru-cache');
var cache = LRU({
max: 2000,
length: function () { return 1; },
maxAge: 1000 * 60 * 60,
});
module.exports = function (User) { module.exports = function (User) {
User.settingsCache = cache;
pubsub.on('user:settings:cache:del', function (uid) {
cache.del('user:' + uid + ':settings');
});
User.getSettings = function (uid, callback) { User.getSettings = function (uid, callback) {
if (!parseInt(uid, 10)) { if (!parseInt(uid, 10)) {
return onSettingsLoaded(0, {}, callback); return onSettingsLoaded(0, {}, callback);
} }
var cached = cache.get('user:' + uid + ':settings');
if (cached) {
return onSettingsLoaded(uid, _.clone(cached || {}), callback);
}
async.waterfall([ async.waterfall([
function (next) { function (next) {
db.getObject('user:' + uid + ':settings', next); db.getObject('user:' + uid + ':settings', next);
@ -41,36 +20,17 @@ module.exports = function (User) {
function (settings, next) { function (settings, next) {
settings = settings || {}; settings = settings || {};
settings.uid = uid; settings.uid = uid;
cache.set('user:' + uid + ':settings', settings); onSettingsLoaded(uid, settings, next);
onSettingsLoaded(uid, _.clone(settings || {}), next);
}, },
], callback); ], callback);
}; };
User.getMultipleUserSettings = function (uids, callback) { User.getMultipleUserSettings = function (uids, callback) {
function getFromCache(next) {
var settings = uids.map(function (uid) {
return cache.get('user:' + uid + ':settings') || {};
});
async.map(settings, function (setting, next) {
onSettingsLoaded(setting.uid, _.clone(setting), next);
}, next);
}
if (!Array.isArray(uids) || !uids.length) { if (!Array.isArray(uids) || !uids.length) {
return callback(null, []); return callback(null, []);
} }
var nonCachedUids = uids.filter(function (uid) { var keys = uids.map(function (uid) {
return !cache.has('user:' + uid + ':settings');
});
if (!nonCachedUids.length) {
return getFromCache(callback);
}
var keys = nonCachedUids.map(function (uid) {
return 'user:' + uid + ':settings'; return 'user:' + uid + ':settings';
}); });
@ -79,13 +39,13 @@ module.exports = function (User) {
db.getObjects(keys, next); db.getObjects(keys, next);
}, },
function (settings, next) { function (settings, next) {
settings.forEach(function (userSettings, index) { settings = settings.map(function (userSettings, index) {
userSettings = userSettings || {}; userSettings = userSettings || {};
userSettings.uid = nonCachedUids[index]; userSettings.uid = uids[index];
cache.set('user:' + userSettings.uid + ':settings', userSettings); return userSettings;
}); });
getFromCache(next); next(null, settings);
}, },
], callback); ], callback);
}; };
@ -187,8 +147,6 @@ module.exports = function (User) {
User.updateDigestSetting(uid, data.dailyDigestFreq, next); User.updateDigestSetting(uid, data.dailyDigestFreq, next);
}, },
function (next) { function (next) {
cache.del('user:' + uid + ':settings');
pubsub.publish('user:settings:cache:del', uid);
User.getSettings(uid, next); User.getSettings(uid, next);
}, },
], callback); ], callback);
@ -213,7 +171,7 @@ module.exports = function (User) {
if (!parseInt(uid, 10)) { if (!parseInt(uid, 10)) {
return setImmediate(callback); return setImmediate(callback);
} }
cache.del('user:' + uid + ':settings');
db.setObjectField('user:' + uid + ':settings', key, value, callback); db.setObjectField('user:' + uid + ':settings', key, value, callback);
}; };
}; };

@ -27,20 +27,21 @@
</div> </div>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"><i class="fa fa-calendar-o"></i> User Settings Cache</div> <div class="panel-heading"><i class="fa fa-calendar-o"></i> Object Cache</div>
<div class="panel-body"> <div class="panel-body">
<label>[[admin/advanced/cache:items-in-cache]]</label><br/>
<span>{userSettingsCache.itemCount}</span><br/>
<label>[[admin/advanced/cache:length-to-max]]</label><br/> <label>[[admin/advanced/cache:length-to-max]]</label><br/>
<span>{userSettingsCache.length} / {userSettingsCache.max}</span><br/> <span>{objectCache.length} / {objectCache.max}</span><br/>
<div class="progress"> <div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="{userSettingsCache.percentFull}" aria-valuemin="0" aria-valuemax="100" style="width: {userSettingsCache.percentFull}%;"> <div class="progress-bar" role="progressbar" aria-valuenow="{objectCache.percentFull}" aria-valuemin="0" aria-valuemax="100" style="width: {objectCache.percentFull}%;">
[[admin/advanced/cache:percent-full, {userSettingsCache.percentFull}]] [[admin/advanced/cache:percent-full, {objectCache.percentFull}]]
</div> </div>
</div> </div>
<!-- IF objectCache.dump -->
<pre>{objectCache.dump}</pre>
<!-- ENDIF objectCache.dump -->
</div> </div>
</div> </div>
@ -48,9 +49,6 @@
<div class="panel-heading"><i class="fa fa-calendar-o"></i> Group Cache</div> <div class="panel-heading"><i class="fa fa-calendar-o"></i> Group Cache</div>
<div class="panel-body"> <div class="panel-body">
<label>[[admin/advanced/cache:items-in-cache]]</label><br/>
<span>{groupCache.itemCount}</span><br/>
<label>[[admin/advanced/cache:length-to-max]]</label><br/> <label>[[admin/advanced/cache:length-to-max]]</label><br/>
<span>{groupCache.length} / {groupCache.max}</span><br/> <span>{groupCache.length} / {groupCache.max}</span><br/>

@ -19,8 +19,8 @@ describe('Hash methods', function () {
describe('setObject()', function () { describe('setObject()', function () {
it('should create a object', function (done) { it('should create a object', function (done) {
db.setObject('testObject1', { foo: 'baris', bar: 99 }, function (err) { db.setObject('testObject1', { foo: 'baris', bar: 99 }, function (err) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
done(); done();
}); });
}); });
@ -57,16 +57,16 @@ describe('Hash methods', function () {
describe('setObjectField()', function () { describe('setObjectField()', function () {
it('should create a new object with field', function (done) { it('should create a new object with field', function (done) {
db.setObjectField('testObject2', 'name', 'ginger', function (err) { db.setObjectField('testObject2', 'name', 'ginger', function (err) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
done(); done();
}); });
}); });
it('should add a new field to an object', function (done) { it('should add a new field to an object', function (done) {
db.setObjectField('testObject2', 'type', 'cat', function (err) { db.setObjectField('testObject2', 'type', 'cat', function (err) {
assert.equal(err, null); assert.ifError(err, null);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
done(); done();
}); });
}); });
@ -305,10 +305,10 @@ describe('Hash methods', function () {
it('should delete an objects field', function (done) { it('should delete an objects field', function (done) {
db.deleteObjectField('testObject10', 'delete', function (err) { db.deleteObjectField('testObject10', 'delete', function (err) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
db.isObjectField('testObject10', 'delete', function (err, isField) { db.isObjectField('testObject10', 'delete', function (err, isField) {
assert.equal(err, null); assert.ifError(err);
assert.equal(isField, false); assert.equal(isField, false);
done(); done();
}); });
@ -318,7 +318,7 @@ describe('Hash methods', function () {
it('should delete multiple fields of the object', function (done) { it('should delete multiple fields of the object', function (done) {
db.deleteObjectFields('testObject10', ['delete1', 'delete2'], function (err) { db.deleteObjectFields('testObject10', ['delete1', 'delete2'], function (err) {
assert.ifError(err); assert.ifError(err);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
async.parallel({ async.parallel({
delete1: async.apply(db.isObjectField, 'testObject10', 'delete1'), delete1: async.apply(db.isObjectField, 'testObject10', 'delete1'),
delete2: async.apply(db.isObjectField, 'testObject10', 'delete2'), delete2: async.apply(db.isObjectField, 'testObject10', 'delete2'),

@ -12,15 +12,15 @@ describe('Key methods', function () {
it('should set a key without error', function (done) { it('should set a key without error', function (done) {
db.set('testKey', 'testValue', function (err) { db.set('testKey', 'testValue', function (err) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
done(); done();
}); });
}); });
it('should get a key without error', function (done) { it('should get a key without error', function (done) {
db.get('testKey', function (err, value) { db.get('testKey', function (err, value) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 2); assert.equal(arguments.length, 2);
assert.strictEqual(value, 'testValue'); assert.strictEqual(value, 'testValue');
done(); done();
@ -29,7 +29,7 @@ describe('Key methods', function () {
it('should return true if key exist', function (done) { it('should return true if key exist', function (done) {
db.exists('testKey', function (err, exists) { db.exists('testKey', function (err, exists) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 2); assert.equal(arguments.length, 2);
assert.strictEqual(exists, true); assert.strictEqual(exists, true);
done(); done();
@ -38,7 +38,7 @@ describe('Key methods', function () {
it('should return false if key does not exist', function (done) { it('should return false if key does not exist', function (done) {
db.exists('doesnotexist', function (err, exists) { db.exists('doesnotexist', function (err, exists) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 2); assert.equal(arguments.length, 2);
assert.strictEqual(exists, false); assert.strictEqual(exists, false);
done(); done();
@ -47,11 +47,11 @@ describe('Key methods', function () {
it('should delete a key without error', function (done) { it('should delete a key without error', function (done) {
db.delete('testKey', function (err) { db.delete('testKey', function (err) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
db.get('testKey', function (err, value) { db.get('testKey', function (err, value) {
assert.equal(err, null); assert.ifError(err);
assert.equal(false, !!value); assert.equal(false, !!value);
done(); done();
}); });
@ -60,10 +60,10 @@ describe('Key methods', function () {
it('should return false if key was deleted', function (done) { it('should return false if key was deleted', function (done) {
db.delete('testKey', function (err) { db.delete('testKey', function (err) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
db.exists('testKey', function (err, exists) { db.exists('testKey', function (err, exists) {
assert.equal(err, null); assert.ifError(err);
assert.strictEqual(exists, false); assert.strictEqual(exists, false);
done(); done();
}); });
@ -83,7 +83,7 @@ describe('Key methods', function () {
return done(err); return done(err);
} }
db.deleteAll(['key1', 'key2'], function (err) { db.deleteAll(['key1', 'key2'], function (err) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 1); assert.equal(arguments.length, 1);
async.parallel({ async.parallel({
key1exists: function (next) { key1exists: function (next) {
@ -93,7 +93,7 @@ describe('Key methods', function () {
db.exists('key2', next); db.exists('key2', next);
}, },
}, function (err, results) { }, function (err, results) {
assert.equal(err, null); assert.ifError(err);
assert.equal(results.key1exists, false); assert.equal(results.key1exists, false);
assert.equal(results.key2exists, false); assert.equal(results.key2exists, false);
done(); done();
@ -124,7 +124,7 @@ describe('Key methods', function () {
db.isSortedSetMember('deletezset', 'value2', next); db.isSortedSetMember('deletezset', 'value2', next);
}, },
}, function (err, results) { }, function (err, results) {
assert.equal(err, null); assert.ifError(err);
assert.equal(results.key1exists, false); assert.equal(results.key1exists, false);
assert.equal(results.key2exists, false); assert.equal(results.key2exists, false);
done(); done();
@ -136,7 +136,7 @@ describe('Key methods', function () {
describe('increment', function () { describe('increment', function () {
it('should initialize key to 1', function (done) { it('should initialize key to 1', function (done) {
db.increment('keyToIncrement', function (err, value) { db.increment('keyToIncrement', function (err, value) {
assert.equal(err, null); assert.ifError(err);
assert.strictEqual(parseInt(value, 10), 1); assert.strictEqual(parseInt(value, 10), 1);
done(); done();
}); });
@ -144,7 +144,7 @@ describe('Key methods', function () {
it('should increment key to 2', function (done) { it('should increment key to 2', function (done) {
db.increment('keyToIncrement', function (err, value) { db.increment('keyToIncrement', function (err, value) {
assert.equal(err, null); assert.ifError(err);
assert.strictEqual(parseInt(value, 10), 2); assert.strictEqual(parseInt(value, 10), 2);
done(); done();
}); });
@ -158,11 +158,11 @@ describe('Key methods', function () {
return done(err); return done(err);
} }
db.rename('keyOldName', 'keyNewName', function (err) { db.rename('keyOldName', 'keyNewName', function (err) {
assert.equal(err, null); assert.ifError(err);
assert.equal(arguments.length, 1); assert(arguments.length < 2);
db.get('keyNewName', function (err, value) { db.get('keyNewName', function (err, value) {
assert.equal(err, null); assert.ifError(err);
assert.equal(value, 'renamedKeyValue'); assert.equal(value, 'renamedKeyValue');
done(); done();
}); });
@ -170,4 +170,69 @@ describe('Key methods', function () {
}); });
}); });
}); });
describe('type', function () {
it('should return null if key does not exist', function (done) {
db.type('doesnotexist', function (err, type) {
assert.ifError(err);
assert.strictEqual(type, null);
done();
});
});
it('should return hash as type', function (done) {
db.setObject('typeHash', { foo: 1 }, function (err) {
assert.ifError(err);
db.type('typeHash', function (err, type) {
assert.ifError(err);
assert.equal(type, 'hash');
done();
});
});
});
it('should return zset as type', function (done) {
db.sortedSetAdd('typeZset', 123, 'value1', function (err) {
assert.ifError(err);
db.type('typeZset', function (err, type) {
assert.ifError(err);
assert.equal(type, 'zset');
done();
});
});
});
it('should return set as type', function (done) {
db.setAdd('typeSet', 'value1', function (err) {
assert.ifError(err);
db.type('typeSet', function (err, type) {
assert.ifError(err);
assert.equal(type, 'set');
done();
});
});
});
it('should return list as type', function (done) {
db.listAppend('typeList', 'value1', function (err) {
assert.ifError(err);
db.type('typeList', function (err, type) {
assert.ifError(err);
assert.equal(type, 'list');
done();
});
});
});
it('should return string as type', function (done) {
db.set('typeString', 'value1', function (err) {
assert.ifError(err);
db.type('typeString', function (err, type) {
assert.ifError(err);
assert.equal(type, 'string');
done();
});
});
});
});
}); });

@ -1,2 +1,3 @@
--reporter dot --reporter dot
--timeout 25000 --timeout 25000
--exit

@ -77,6 +77,15 @@ describe('Upload Controllers', function () {
}); });
}); });
it('should fail to upload an image to a post with invalid cid', function (done) {
helpers.uploadFile(nconf.get('url') + '/api/post/upload', path.join(__dirname, '../test/files/test.png'), { cid: '0' }, jar, csrf_token, function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 500);
assert.equal(body.error, '[[error:category-not-selected]]');
done();
});
});
it('should upload an image to a post', function (done) { it('should upload an image to a post', function (done) {
helpers.uploadFile(nconf.get('url') + '/api/post/upload', path.join(__dirname, '../test/files/test.png'), { cid: cid }, jar, csrf_token, function (err, res, body) { helpers.uploadFile(nconf.get('url') + '/api/post/upload', path.join(__dirname, '../test/files/test.png'), { cid: cid }, jar, csrf_token, function (err, res, body) {
assert.ifError(err); assert.ifError(err);

Loading…
Cancel
Save