Selaa lähdekoodia

Merge remote-tracking branch 'FreshRSS/dev' into dev

Alexandre Alapetite 8 vuotta sitten
vanhempi
commit
e12f9d4a98

+ 5 - 0
CHANGELOG.md

@@ -20,10 +20,13 @@
 	* Fix UI lowest subscription popup hidden [#1479](https://github.com/FreshRSS/FreshRSS/issues/1479)
 	* Fix update system via ZIP archive [#1498](https://github.com/FreshRSS/FreshRSS/pull/1498)
 	* Work around for IE / Edge bug in username pattern in version 1.6.3 [#1511](https://github.com/FreshRSS/FreshRSS/issues/1511)
+	* Fix *mark as read* articles when adding a new feed [#1535](https://github.com/FreshRSS/FreshRSS/issues/1535)
 * UI
 	* Download icon 💾 for other MIME types (e.g. `application/*`) [#1522](https://github.com/FreshRSS/FreshRSS/pull/1522)
 * I18n
 	* Improve English [#1465](https://github.com/FreshRSS/FreshRSS/pull/1465)
+* Security
+	* Do not require write access to check availability of new versions [#1450](https://github.com/FreshRSS/FreshRSS/issues/1450)
 * Misc.
 	* Moved `./data/force-https.default.txt` to `./force-https.default.txt`,
 		`./data/config.default.php` to `./config.default.php`,
@@ -54,6 +57,8 @@
 	* Fix PostgreSQL bugs with API and feed modifications [#1417](https://github.com/FreshRSS/FreshRSS/pull/1417)
 	* Do not mark as read in anonymous mode [#1431](https://github.com/FreshRSS/FreshRSS/issues/1431)
 	* Fix Favicons warnings [#59dfc64](https://github.com/FreshRSS/FreshRSS/commit/59dfc64512372eaba7609d84500d943bb7274399), [#1452](https://github.com/FreshRSS/FreshRSS/pull/1452)
+* I18n
+	* Simplified Chinese [#1541](https://github.com/FreshRSS/FreshRSS/pull/1541)
 * Security
 	* Sanitize feed Web site URL [#1434](https://github.com/FreshRSS/FreshRSS/issues/1434)
 	* No version number for anonymous users [#1404](https://github.com/FreshRSS/FreshRSS/issues/1404)

+ 1 - 0
CREDITS.md

@@ -21,6 +21,7 @@ People are sorted by name so please keep this order.
 * [Guillaume Fillon](https://github.com/kokaz): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:kokaz), [Web](http://www.guillaume-fillon.com/)
 * [Guillaume Hayot](https://github.com/postblue): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:postblue), [Web](https://postblue.info/)
 * [hckweb](https://github.com/hckweb): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=hckweb)
+* [hoilc](https://github.com/hoilc): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:hoilc)
 * [Jaussoin Timothée](https://github.com/edhelas): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=edhelas), [Web](http://edhelas.movim.eu/)
 * [jlefler](https://github.com/jlefler): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:jlefler)
 * [Jonas Östanbäck](https://github.com/cez81): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=cez81)

+ 1 - 0
README.md

@@ -105,6 +105,7 @@ cd /usr/share/FreshRSS
 sudo git pull
 sudo chown -R :www-data . && sudo chmod -R g+r . && sudo chmod -R g+w ./data/
 ```
+See more commands and git commands in the [Command-Line Interface documentation](./cli/README.md).
 
 ## Access control
 It is needed for the multi-user mode to limit access to FreshRSS. You can:

+ 1 - 0
app/Controllers/feedController.php

@@ -348,6 +348,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
 					} else {
 						if ($isNewFeed) {
 							$id = min(time(), $entry_date) . uSecString();
+							$entry->_isRead($is_read);
 						} elseif ($entry_date < $date_min) {
 							$id = min(time(), $entry_date) . uSecString();
 							$entry->_isRead(true);	//Old article that was not in database. Probably an error, so mark as read

+ 16 - 14
app/Controllers/updateController.php

@@ -59,24 +59,26 @@ class FreshRSS_update_Controller extends Minz_ActionController {
 	public function indexAction() {
 		Minz_View::prependTitle(_t('admin.update.title') . ' · ');
 
-		if (!is_writable(FRESHRSS_PATH)) {
-			$this->view->message = array(
-				'status' => 'bad',
-				'title' => _t('gen.short.damn'),
-				'body' => _t('feedback.update.file_is_nok', FRESHRSS_PATH)
-			);
-		} elseif (file_exists(UPDATE_FILENAME)) {
+		if (file_exists(UPDATE_FILENAME)) {
 			// There is an update file to apply!
 			$version = @file_get_contents(join_path(DATA_PATH, 'last_update.txt'));
-			if (empty($version)) {
+			if ($version == '') {
 				$version = 'unknown';
 			}
-			$this->view->update_to_apply = true;
-			$this->view->message = array(
-				'status' => 'good',
-				'title' => _t('gen.short.ok'),
-				'body' => _t('feedback.update.can_apply', $version)
-			);
+			if (is_writable(FRESHRSS_PATH)) {
+				$this->view->update_to_apply = true;
+				$this->view->message = array(
+					'status' => 'good',
+					'title' => _t('gen.short.ok'),
+					'body' => _t('feedback.update.can_apply', $version),
+				);
+			} else {
+				$this->view->message = array(
+					'status' => 'bad',
+					'title' => _t('gen.short.damn'),
+					'body' => _t('feedback.update.file_is_nok', $version, FRESHRSS_PATH),
+				);
+			}
 		}
 	}
 

+ 1 - 1
app/i18n/cz/feedback.php

@@ -87,7 +87,7 @@ return array(
 	'update' => array(
 		'can_apply' => 'FreshRSS bude nyní upgradováno na <strong>verzi %s</strong>.',
 		'error' => 'Během upgrade došlo k chybě: %s',
-		'file_is_nok' => 'Zkontrolujte oprávnění adresáře <em>%s</em>. HTTP server musí mít do tohoto adresáře práva zápisu',
+		'file_is_nok' => '<strong>Verzi %s</strong>. Zkontrolujte oprávnění adresáře <em>%s</em>. HTTP server musí mít do tohoto adresáře práva zápisu',
 		'finished' => 'Upgrade hotov!',
 		'none' => 'Novější verze není k dispozici',
 		'server_not_found' => 'Nelze nalézt server s instalačním souborem. [%s]',

+ 1 - 1
app/i18n/de/feedback.php

@@ -87,7 +87,7 @@ return array(
 	'update' => array(
 		'can_apply' => 'FreshRSS wird nun auf die <strong>Version %s</strong> aktualisiert.',
 		'error' => 'Der Aktualisierungsvorgang stieß auf einen Fehler: %s',
-		'file_is_nok' => 'Überprüfen Sie die Berechtigungen des Verzeichnisses <em>%s</em>. Der HTTP-Server muss Schreibrechte besitzen',
+		'file_is_nok' => '<strong>Version %s</strong>. Überprüfen Sie die Berechtigungen des Verzeichnisses <em>%s</em>. Der HTTP-Server muss Schreibrechte besitzen',
 		'finished' => 'Aktualisierung abgeschlossen!',
 		'none' => 'Keine Aktualisierung zum Anwenden',
 		'server_not_found' => 'Der Aktualisierungs-Server kann nicht gefunden werden. [%s]',

+ 1 - 1
app/i18n/en/feedback.php

@@ -87,7 +87,7 @@ return array(
 	'update' => array(
 		'can_apply' => 'FreshRSS will now be updated to the <strong>version %s</strong>.',
 		'error' => 'The update process has encountered an error: %s',
-		'file_is_nok' => 'Check permissions on <em>%s</em> directory. HTTP server must have rights to write into',
+		'file_is_nok' => 'New <strong>version %s</strong> available, but check permissions on <em>%s</em> directory. HTTP server must have rights to write into',
 		'finished' => 'Update completed!',
 		'none' => 'No update to apply',
 		'server_not_found' => 'Update server cannot be found. [%s]',

+ 1 - 0
app/i18n/en/gen.php

@@ -121,6 +121,7 @@ return array(
 		'nl' => 'Nederlands',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
+		'zh-cn' => '简体中文'
 	),
 	'menu' => array(
 		'about' => 'About',

+ 1 - 1
app/i18n/fr/feedback.php

@@ -87,7 +87,7 @@ return array(
 	'update' => array(
 		'can_apply' => 'FreshRSS va maintenant être mis à jour vers la <strong>version %s</strong>.',
 		'error' => 'La mise à jour a rencontré un problème : %s',
-		'file_is_nok' => 'Veuillez vérifier les droits sur le répertoire <em>%s</em>. Le serveur HTTP doit être capable d’écrire dedans',
+		'file_is_nok' => 'Nouvelle <strong>version %s</strong> disponible, mais veuillez vérifier les droits sur le répertoire <em>%s</em>. Le serveur HTTP doit être capable d’écrire dedans',
 		'finished' => 'La mise à jour est terminée !',
 		'none' => 'Aucune mise à jour à appliquer',
 		'server_not_found' => 'Le serveur de mise à jour n’a pas été trouvé. [%s]',

+ 1 - 1
app/i18n/it/feedback.php

@@ -87,7 +87,7 @@ return array(
 	'update' => array(
 		'can_apply' => 'FreshRSS verrà aggiornato alla <strong>versione %s</strong>.',
 		'error' => 'Il processo di aggiornamento ha riscontrato il seguente errore: %s',
-		'file_is_nok' => 'Verifica i permessi della cartella <em>%s</em>. Il server HTTP deve avere i permessi per la scrittura ',
+		'file_is_nok' => 'Nuova <strong>versione %s</strong>, ma verifica i permessi della cartella <em>%s</em>. Il server HTTP deve avere i permessi per la scrittura ',
 		'finished' => 'Aggiornamento completato con successo!',
 		'none' => 'Nessun aggiornamento disponibile',
 		'server_not_found' => 'Server per aggiornamento non disponibile. [%s]',

+ 1 - 1
app/i18n/nl/feedback.php

@@ -87,7 +87,7 @@ return array(
 	'update' => array(
 		'can_apply' => 'FreshRSS word nu vernieud naar <strong>versie %s</strong>.',
 		'error' => 'Het vernieuwingsproces kwam een fout tegen: %s',
-		'file_is_nok' => 'Controleer permissies op <em>%s</em> map. HTTP server moet rechten hebben om er in te schrijven',
+		'file_is_nok' => '<strong>Versie %s</strong>. Controleer permissies op <em>%s</em> map. HTTP server moet rechten hebben om er in te schrijven',
 		'finished' => 'Vernieuwing compleet!',
 		'none' => 'Geen vernieuwing om toe te passen',
 		'server_not_found' => 'Vernieuwings server kan niet worden gevonden. [%s]',

+ 67 - 67
app/i18n/ru/feedback.php

@@ -2,108 +2,108 @@
 
 return array(
 	'admin' => array(
-		'optimization_complete' => 'Optimisation complete',
+		'optimization_complete' => 'Optimisation complete',	//TODO
 	),
 	'access' => array(
-		'denied' => 'You don’t have permission to access this page',
-		'not_found' => 'You are looking for a page which doesn’t exist',
+		'denied' => 'You don’t have permission to access this page',	//TODO
+		'not_found' => 'You are looking for a page which doesn’t exist',	//TODO
 	),
 	'auth' => array(
 		'form' => array(
-			'not_set' => 'A problem occured during authentication system configuration. Please retry later.',
-			'set' => 'Form is now your default authentication system.',
+			'not_set' => 'A problem occured during authentication system configuration. Please retry later.',	//TODO
+			'set' => 'Form is now your default authentication system.',	//TODO
 		),
 		'login' => array(
-			'invalid' => 'Login is invalid',
-			'success' => 'You are connected',
+			'invalid' => 'Login is invalid',	//TODO
+			'success' => 'You are connected',	//TODO
 		),
 		'logout' => array(
-			'success' => 'You are disconnected',
+			'success' => 'You are disconnected',	//TODO
 		),
-		'no_password_set' => 'Administrator password hasn’t been set. This feature isn’t available.',
+		'no_password_set' => 'Administrator password hasn’t been set. This feature isn’t available.',	//TODO
 	),
 	'conf' => array(
-		'error' => 'An error occurred during configuration saving',
-		'query_created' => 'Query "%s" has been created.',
-		'shortcuts_updated' => 'Shortcuts have been updated',
-		'updated' => 'Configuration has been updated',
+		'error' => 'An error occurred during configuration saving',	//TODO
+		'query_created' => 'Query "%s" has been created.',	//TODO
+		'shortcuts_updated' => 'Shortcuts have been updated',	//TODO
+		'updated' => 'Configuration has been updated',	//TODO
 	),
 	'extensions' => array(
-		'already_enabled' => '%s is already enabled',
+		'already_enabled' => '%s is already enabled',	//TODO
 		'disable' => array(
-			'ko' => '%s cannot be disabled. <a href="%s">Check FressRSS logs</a> for details.',
-			'ok' => '%s is now disabled',
+			'ko' => '%s cannot be disabled. <a href="%s">Check FressRSS logs</a> for details.',	//TODO
+			'ok' => '%s is now disabled',	//TODO
 		),
 		'enable' => array(
-			'ko' => '%s cannot be enabled. <a href="%s">Check FressRSS logs</a> for details.',
-			'ok' => '%s is now enabled',
+			'ko' => '%s cannot be enabled. <a href="%s">Check FressRSS logs</a> for details.',	//TODO
+			'ok' => '%s is now enabled',	//TODO
 		),
-		'no_access' => 'You have no access on %s',
-		'not_enabled' => '%s is not enabled yet',
-		'not_found' => '%s does not exist',
+		'no_access' => 'You have no access on %s',	//TODO
+		'not_enabled' => '%s is not enabled yet',	//TODO
+		'not_found' => '%s does not exist',	//TODO
 	),
 	'import_export' => array(
-		'export_no_zip_extension' => 'ZIP extension is not present on your server. Please try to export files one by one.',
-		'feeds_imported' => 'Your feeds have been imported and will now be updated',
-		'feeds_imported_with_errors' => 'Your feeds have been imported but some errors occurred',
-		'file_cannot_be_uploaded' => 'File cannot be uploaded!',
-		'no_zip_extension' => 'ZIP extension is not present on your server.',
-		'zip_error' => 'An error occured during ZIP import.',
+		'export_no_zip_extension' => 'ZIP extension is not present on your server. Please try to export files one by one.',	//TODO
+		'feeds_imported' => 'Your feeds have been imported and will now be updated',	//TODO
+		'feeds_imported_with_errors' => 'Your feeds have been imported but some errors occurred',	//TODO
+		'file_cannot_be_uploaded' => 'File cannot be uploaded!',	//TODO
+		'no_zip_extension' => 'ZIP extension is not present on your server.',	//TODO
+		'zip_error' => 'An error occured during ZIP import.',	//TODO
 	),
 	'sub' => array(
-		'actualize' => 'Actualise',
+		'actualize' => 'Actualise',	//TODO
 		'category' => array(
-			'created' => 'Category %s has been created.',
-			'deleted' => 'Category has been deleted.',
-			'emptied' => 'Category has been emptied',
-			'error' => 'Category cannot be updated',
-			'name_exists' => 'Category name already exists.',
-			'no_id' => 'You must precise the id of the category.',
-			'no_name' => 'Category name cannot be empty.',
-			'not_delete_default' => 'You cannot delete the default category!',
-			'not_exist' => 'The category does not exist!',
-			'over_max' => 'You have reached your limit of categories (%d)',
-			'updated' => 'Category has been updated.',
+			'created' => 'Category %s has been created.',	//TODO
+			'deleted' => 'Category has been deleted.',	//TODO
+			'emptied' => 'Category has been emptied',	//TODO
+			'error' => 'Category cannot be updated',	//TODO
+			'name_exists' => 'Category name already exists.',	//TODO
+			'no_id' => 'You must precise the id of the category.',	//TODO
+			'no_name' => 'Category name cannot be empty.',	//TODO
+			'not_delete_default' => 'You cannot delete the default category!',	//TODO
+			'not_exist' => 'The category does not exist!',	//TODO
+			'over_max' => 'You have reached your limit of categories (%d)',	//TODO
+			'updated' => 'Category has been updated.',	//TODO
 		),
 		'feed' => array(
-			'actualized' => '<em>%s</em> has been updated',
-			'actualizeds' => 'RSS feeds have been updated',
-			'added' => 'RSS feed <em>%s</em> has been added',
-			'already_subscribed' => 'You have already subscribed to <em>%s</em>',
-			'deleted' => 'Feed has been deleted',
-			'error' => 'Feed cannot be updated',
-			'internal_problem' => 'The RSS feed could not be added. <a href="%s">Check FressRSS logs</a> for details.',
-			'invalid_url' => 'URL <em>%s</em> is invalid',
-			'marked_read' => 'Feeds have been marked as read',
-			'n_actualized' => '%d feeds have been updated',
-			'n_entries_deleted' => '%d articles have been deleted',
-			'no_refresh' => 'There is no feed to refresh…',
-			'not_added' => '<em>%s</em> could not be added',
-			'over_max' => 'You have reached your limit of feeds (%d)',
-			'updated' => 'Feed has been updated',
+			'actualized' => '<em>%s</em> has been updated',	//TODO
+			'actualizeds' => 'RSS feeds have been updated',	//TODO
+			'added' => 'RSS feed <em>%s</em> has been added',	//TODO
+			'already_subscribed' => 'You have already subscribed to <em>%s</em>',	//TODO
+			'deleted' => 'Feed has been deleted',	//TODO
+			'error' => 'Feed cannot be updated',	//TODO
+			'internal_problem' => 'The RSS feed could not be added. <a href="%s">Check FressRSS logs</a> for details.',	//TODO
+			'invalid_url' => 'URL <em>%s</em> is invalid',	//TODO
+			'marked_read' => 'Feeds have been marked as read',	//TODO
+			'n_actualized' => '%d feeds have been updated',	//TODO
+			'n_entries_deleted' => '%d articles have been deleted',	//TODO
+			'no_refresh' => 'There is no feed to refresh…',	//TODO
+			'not_added' => '<em>%s</em> could not be added',	//TODO
+			'over_max' => 'You have reached your limit of feeds (%d)',	//TODO
+			'updated' => 'Feed has been updated',	//TODO
 		),
-		'purge_completed' => 'Purge completed (%d articles deleted)',
+		'purge_completed' => 'Purge completed (%d articles deleted)',	//TODO
 	),
 	'update' => array(
-		'can_apply' => 'FreshRSS will now be updated to the <strong>version %s</strong>.',
-		'error' => 'The update process has encountered an error: %s',
-		'file_is_nok' => 'Check permissions on <em>%s</em> directory. HTTP server must have rights to write into',
-		'finished' => 'Update completed!',
-		'none' => 'No update to apply',
-		'server_not_found' => 'Update server cannot be found. [%s]',
+		'can_apply' => 'FreshRSS will now be updated to the <strong>version %s</strong>.',	//TODO
+		'error' => 'The update process has encountered an error: %s',	//TODO
+		'file_is_nok' => 'New <strong>version %s</strong> available, but check permissions on <em>%s</em> directory. HTTP server must have rights to write into',	//TODO
+		'finished' => 'Update completed!',	//TODO
+		'none' => 'No update to apply',	//TODO
+		'server_not_found' => 'Update server cannot be found. [%s]',	//TODO
 	),
 	'user' => array(
 		'created' => array(
-			'_' => 'User %s has been created',
-			'error' => 'User %s cannot be created',
+			'_' => 'User %s has been created',	//TODO
+			'error' => 'User %s cannot be created',	//TODO
 		),
 		'deleted' => array(
-			'_' => 'User %s has been deleted',
-			'error' => 'User %s cannot be deleted',
+			'_' => 'User %s has been deleted',	//TODO
+			'error' => 'User %s cannot be deleted',	//TODO
 		),
 	),
 	'profile' => array(
-		'error' => 'Your profile cannot be modified',
-		'updated' => 'Your profile has been modified',
+		'error' => 'Your profile cannot be modified',	//TODO
+		'updated' => 'Your profile has been modified',	//TODO
 	),
 );

+ 1 - 1
app/i18n/tr/feedback.php

@@ -87,7 +87,7 @@ return array(
 	'update' => array(
 		'can_apply' => 'FreshRSS <strong>%s versiyonuna</strong> güncellenecek.',
 		'error' => 'Güncelleme işlemi sırasında hata: %s',
-		'file_is_nok' => '<em>%s</em> klasör yetkisini kontrol edin. HTTP yazma yetkisi olmalı',
+		'file_is_nok' => '<strong>%s versiyonuna</strong>. <em>%s</em> klasör yetkisini kontrol edin. HTTP yazma yetkisi olmalı',
 		'finished' => 'Güncelleme tamamlandı!',
 		'none' => 'Güncelleme yok',
 		'server_not_found' => 'Güncelleme sunucusu bulunamadı. [%s]',

+ 181 - 0
app/i18n/zh-cn/admin.php

@@ -0,0 +1,181 @@
+<?php
+
+return array(
+	'auth' => array(
+		'allow_anonymous' => '允许匿名阅读默认用户 (%s) 的文章',
+		'allow_anonymous_refresh' => '允许匿名刷新文章',
+		'api_enabled' => '允许 <abbr>API</abbr> 访问 <small>(用于手机 APP)</small>',
+		'form' => 'Web form (传统方式, 需要 JavaScript)',
+		'http' => 'HTTP (面向启用 HTTPS 的高级用户)',
+		'none' => '无 (危险)',
+		'title' => '认证',
+		'title_reset' => '认证重置',
+		'token' => '认证口令',
+		'token_help' => '允许不经认证访问默认用户的 RSS 输出:',
+		'type' => '认证方式',
+		'unsafe_autologin' => '允许不安全的自动登陆方式:',
+	),
+	'check_install' => array(
+		'cache' => array(
+			'nok' => '请检查 <em>./data/cache</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'cache 目录权限正常。',
+		),
+		'categories' => array(
+			'nok' => '分类表配置错误。',
+			'ok' => '分类表正常。',
+		),
+		'connection' => array(
+			'nok' => '数据库连接失败。',
+			'ok' => '数据库连接正常。',
+		),
+		'ctype' => array(
+			'nok' => '找不到字符类型检测库 (php-ctype) 。',
+			'ok' => '你已有字符类型检测库 (ctype) 。',
+		),
+		'curl' => array(
+			'nok' => '找不到 cURL 库 (php-curl package) 。',
+			'ok' => '你已有 cURL 库。',
+		),
+		'data' => array(
+			'nok' => '请检查 <em>./data</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'data 目录权限正常。',
+		),
+		'database' => '数据库相关',
+		'dom' => array(
+			'nok' => '找不到用于浏览 DOM 的库 (php-xml) 。',
+			'ok' => '你已有用于浏览 DOM 的库。',
+		),
+		'entries' => array(
+			'nok' => '条目表配置错误。',
+			'ok' => '条目表正常。',
+		),
+		'favicons' => array(
+			'nok' => '请检查 <em>./data/favicons</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'favicons 目录权限正常。',
+		),
+		'feeds' => array(
+			'nok' => 'RSS 源表配置错误。',
+			'ok' => 'RSS 源表正常。',
+		),
+		'fileinfo' => array(
+			'nok' => '找不到 PHP fileinfo 库 (fileinfo) 。',
+			'ok' => '你已有 fileinfo 库。',
+		),
+		'files' => '文件相关',
+		'json' => array(
+			'nok' => '找不到 JSON 扩展 (php5-json ) 。',
+			'ok' => '你已有 JSON 扩展',
+		),
+		'minz' => array(
+			'nok' => '找不到 Minz 框架。',
+			'ok' => '你已有 Minz 框架。',
+		),
+		'pcre' => array(
+			'nok' => '找不到正则表达式解析库 (php-pcre) 。',
+			'ok' => '你已有正则表达式解析库 (PCRE) 。',
+		),
+		'pdo' => array(
+			'nok' => '找不到 PDO 或支持的驱动 (pdo_mysql, pdo_sqlite, pdo_pgsql) 。',
+			'ok' => '你已有 PDO 和支持的至少一种驱动 (pdo_mysql, pdo_sqlite, pdo_pgsql) 。',
+		),
+		'php' => array(
+			'_' => 'PHP 相关',
+			'nok' => '你的 PHP 版本为 %s,但 FreshRSS 最低需要 %s。',
+			'ok' => '你的 PHP 版本为 %s,与 FreshRSS 兼容。',
+		),
+		'tables' => array(
+			'nok' => '数据库中缺少一个或多个表。',
+			'ok' => '数据库中相关表存在。',
+		),
+		'title' => '环境检查',
+		'tokens' => array(
+			'nok' => '请检查 <em>./data/tokens</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'tokens 目录权限正常。',
+		),
+		'users' => array(
+			'nok' => '请检查 <em>./data/users</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'users 目录权限正常。',
+		),
+		'zip' => array(
+			'nok' => '找不到 ZIP 扩展 (php-zip) 。',
+			'ok' => '你已有 ZIP 扩展。',
+		),
+	),
+	'extensions' => array(
+		'disabled' => '已禁用',
+		'empty_list' => '没有已安装的扩展',
+		'enabled' => '已启用',
+		'no_configure_view' => '此扩展不能配置。',
+		'system' => array(
+			'_' => '系统扩展',
+			'no_rights' => '系统扩展 (你不能修改它)',
+		),
+		'title' => '扩展',
+		'user' => '用户扩展',
+	),
+	'stats' => array(
+		'_' => '统计',
+		'all_feeds' => '所有 RSS 源',
+		'category' => '分类',
+		'entry_count' => '条目数',
+		'entry_per_category' => '每分类条目数',
+		'entry_per_day' => '每天条目数 (最近 30 天)',
+		'entry_per_day_of_week' => '周内每天 (平均: %.2f 条消息)',
+		'entry_per_hour' => '每小时 (平均: %.2f 条消息)',
+		'entry_per_month' => '每月 (平均: %.2f 条消息)',
+		'entry_repartition' => '条目分布',
+		'feed' => 'RSS 源',
+		'feed_per_category' => '每分类 RSS 源',
+		'idle' => '闲置 RSS 源',
+		'main' => '主要统计',
+		'main_stream' => '首页',
+		'menu' => array(
+			'idle' => '闲置 RSS 源',
+			'main' => '主要统计',
+			'repartition' => '文章分布',
+		),
+		'no_idle' => '无闲置 RSS 源!',
+		'number_entries' => '%d 篇文章',
+		'percent_of_total' => '%%',
+		'repartition' => '文章分布',
+		'status_favorites' => '收藏',
+		'status_read' => '已读',
+		'status_total' => '总计',
+		'status_unread' => '未读',
+		'title' => '统计',
+		'top_feed' => '前十 RSS 源',
+	),
+	'system' => array(
+		'_' => '系统配置',
+		'auto-update-url' => '自动升级服务器 URL',
+		'instance-name' => '实例名称',
+		'max-categories' => '每用户分类限制',
+		'max-feeds' => '每用户 RSS 源限制',
+		'registration' => array(
+			'help' => '0 表示无账户数限制',
+			'number' => '最大账户数',
+		),
+	),
+	'update' => array(
+		'_' => '更新系统',
+		'apply' => '应用',
+		'check' => '检查更新',
+		'current_version' => '当前 FreshRSS 版本为 %s.',
+		'last' => '上一次检查: %s',
+		'none' => '没有可用更新',
+		'title' => '更新系统',
+	),
+	'user' => array(
+		'articles_and_size' => '%s 篇文章 (%s)',
+		'create' => '创建新用户',
+		'language' => '语言',
+		'number' => '已有 %d 个帐户',
+		'numbers' => '已有 %d 个帐户',
+		'password_form' => '密码<br /><small>(用于 Web-form 登录方式)</small>',
+		'password_format' => '至少 7 个字符',
+		'title' => '用户管理',
+		'user_list' => '用户列表',
+		'username' => '用户名',
+		'users' => '用户',
+	),
+);

+ 174 - 0
app/i18n/zh-cn/conf.php

@@ -0,0 +1,174 @@
+<?php
+
+return array(
+	'archiving' => array(
+		'_' => '存档',
+		'advanced' => '高级',
+		'delete_after' => '文章保留',
+		'help' => '详细选项位于单独的 RSS 源设置',
+		'keep_history_by_feed' => '至少保存的文章数',
+		'optimize' => '优化数据库',
+		'optimize_help' => '不时地执行优化可以减少数据库大小',
+		'purge_now' => '立即清除',
+		'title' => '存档',
+		'ttl' => '最小自动更新时间',
+	),
+	'display' => array(
+		'_' => '显示',
+		'icon' => array(
+			'bottom_line' => '底栏',
+			'entry' => '文章图标',
+			'publication_date' => '更新日期',
+			'related_tags' => '相关标签',
+			'sharing' => '分享',
+			'top_line' => '顶栏',
+		),
+		'language' => '语言',
+		'notif_html5' => array(
+			'seconds' => '秒 (0 表示不超时)',
+			'timeout' => 'HTML5 通知超时时间',
+		),
+		'theme' => '主题',
+		'title' => '显示',
+		'width' => array(
+			'content' => '内容宽度',
+			'large' => '大',
+			'medium' => '中',
+			'no_limit' => '无限制',
+			'thin' => '小',
+		),
+	),
+	'query' => array(
+		'_' => '自定义查询',
+		'deprecated' => '此查询不再有效。相关的分类或 RSS 源已被删除。',
+		'filter' => '生效的过滤器:',
+		'get_all' => '显示所有文章',
+		'get_category' => '显示分类 "%s"',
+		'get_favorite' => '显示收藏文章',
+		'get_feed' => '显示RSS 源 "%s"',
+		'no_filter' => '无过滤器',
+		'none' => '你未创建任何自定义查询。',
+		'number' => '查询 n°%d',
+		'order_asc' => '由旧到新显示文章',
+		'order_desc' => '由新到旧显示文章',
+		'search' => '搜索 "%s"',
+		'state_0' => '显示所有文章',
+		'state_1' => '显示已读文章',
+		'state_2' => '显示未读文章',
+		'state_3' => '显示所有文章',
+		'state_4' => '显示收藏文章',
+		'state_5' => '显示已读的收藏文章',
+		'state_6' => '显示未读的收藏文章',
+		'state_7' => '显示收藏文章',
+		'state_8' => '显示未收藏文章',
+		'state_9' => '显示已读的未收藏文章',
+		'state_10' => '显示未读的未收藏文章',
+		'state_11' => '显示未收藏文章',
+		'state_12' => '显示所有文章',
+		'state_13' => '显示已读文章',
+		'state_14' => '显示未读文章',
+		'state_15' => '显示所有文章',
+		'title' => '自定义查询',
+	),
+	'profile' => array(
+		'_' => '帐户管理',
+		'delete' => array(
+			'_' => '账户删除',
+			'warn' => '你的帐户和所有相关数据都将被删除。',
+		),
+		'password_api' => 'API 密码<br /><small>(例如,用于手机 APP)</small>',
+		'password_form' => '密码<br /><small>(用于 Web-form 登录方式)</small>',
+		'password_format' => '至少 7 个字符',
+		'title' => '用户帐户',
+	),
+	'reading' => array(
+		'_' => '阅读',
+		'after_onread' => '“全部设为已读”后,',
+		'articles_per_page' => '每页文章数',
+		'auto_load_more' => '在页面底部载入下一篇文章',
+		'auto_remove_article' => '阅读后隐藏文章',
+		'mark_updated_article_unread' => '将有更新的文章设为未读',
+		'confirm_enabled' => '“全部设为已读”时显示确认对话框',
+		'display_articles_unfolded' => '默认展开文章',
+		'display_categories_unfolded' => '默认展开分类',
+		'hide_read_feeds' => '隐藏没有未读文章的分类或 RSS 源 (启用“显示所有文章”时不生效))',
+		'img_with_lazyload' => '使用 "lazy load" 模式加载图片',
+		'sides_close_article' => '点击文章外区域以关闭文章',
+		'jump_next' => '跳转到下一未读项 (RSS 源或分类)',
+		'number_divided_when_reader' => '阅读视图除以 2',
+		'read' => array(
+			'article_open_on_website' => '在打开原文章后',
+			'article_viewed' => '在文章被浏览后',
+			'scroll' => '在滚动浏览后',
+			'upon_reception' => '在接收文章后',
+			'when' => '将文章设为已读…',
+		),
+		'show' => array(
+			'_' => 	'文章显示',
+			'adaptive' => '智能显示',
+			'all_articles' => '显示所有文章',
+			'unread' => '只显示未读',
+		),
+		'sort' => array(
+			'_' => '排列顺序',
+			'newer_first' => '由新到旧',
+			'older_first' => '由旧到新',
+		),
+		'sticky_post' => '打开文章时将其置顶',
+		'title' => '阅读',
+		'view' => array(
+			'default' => '默认视图',
+			'global' => '全屏视图',
+			'normal' => '普通视图',
+			'reader' => '阅读视图',
+		),
+	),
+	'sharing' => array(
+		'_' => '分享',
+		'blogotext' => 'Blogotext',
+		'diaspora' => 'Diaspora*',
+		'email' => 'Email',
+		'facebook' => 'Facebook',
+		'g+' => 'Google+',
+		'more_information' => '更多信息',
+		'print' => '打印',
+		'shaarli' => 'Shaarli',
+		'share_name' => '名称',
+		'share_url' => 'URL',
+		'title' => '分享',
+		'twitter' => 'Twitter',
+		'wallabag' => 'wallabag',
+	),
+	'shortcut' => array(
+		'_' => '快捷键',
+		'article_action' => '文章操作',
+		'auto_share' => '分享',
+		'auto_share_help' => '如果有多种分享模式,则会按照它们的编号访问。',
+		'close_dropdown' => '关闭菜单',
+		'collapse_article' => '收起文章',
+		'first_article' => '跳转到第一篇文章',
+		'focus_search' => '聚焦到搜索框',
+		'help' => '显示帮助文档',
+		'javascript' => '若要使用快捷键,必须启用 JavaScript',
+		'last_article' => '跳转到最后一篇文章',
+		'load_more' => '载入更多文章',
+		'mark_read' => '设为已读',
+		'mark_favorite' => '加入收藏',
+		'navigation' => '浏览',
+		'navigation_help' => '搭配 "Shift" 键,浏览快捷键将生效于 RSS 源。<br/>搭配 "Alt" 键,浏览快捷键将生效于分类。',
+		'next_article' => '跳转到下一篇文章',
+		'other_action' => '其他操作',
+		'previous_article' => '跳转到上一篇文章',
+		'see_on_website' => '在原网站上查看',
+		'shift_for_all_read' => '+ <code>shift</code> 可以将全部文章设为已读',
+		'title' => '快捷键',
+		'user_filter' => '显示自定义查询',
+		'user_filter_help' => '如果有多个自定义过滤器,则会按照它们的编号访问。',
+	),
+	'user' => array(
+		'articles_and_size' => '%s 篇文章 (%s)',
+		'current' => '当前用户',
+		'is_admin' => '此用户为管理员',
+		'users' => '用户',
+	),
+);

+ 109 - 0
app/i18n/zh-cn/feedback.php

@@ -0,0 +1,109 @@
+<?php
+
+return array(
+	'admin' => array(
+		'optimization_complete' => '优化完成',
+	),
+	'access' => array(
+		'denied' => '你无权访问此页面',
+		'not_found' => '你寻找的页面不存在',
+	),
+	'auth' => array(
+		'form' => array(
+			'not_set' => '配置认证方式时出错。请稍后重试。',
+			'set' => 'Form 是你当前默认的认证方式。',
+		),
+		'login' => array(
+			'invalid' => '用户名或密码无效',
+			'success' => '你已成功登录',
+		),
+		'logout' => array(
+			'success' => '你已登出',
+		),
+		'no_password_set' => '管理员密码尚未设置。此特性不可用。',
+	),
+	'conf' => array(
+		'error' => '保存配置时出错',
+		'query_created' => '查询 "%s" 已创建。',
+		'shortcuts_updated' => '快捷键已更新',
+		'updated' => '配置已更新',
+	),
+	'extensions' => array(
+		'already_enabled' => '%s 已启用',
+		'disable' => array(
+			'ko' => '%s 禁用失败。<a href="%s">检查 FressRSS 日志</a> 查看详情。',
+			'ok' => '%s 现已禁用',
+		),
+		'enable' => array(
+			'ko' => '%s 启用失败。<a href="%s">检查 FressRSS 日志</a> 查看详情。',
+			'ok' => '%s 现已禁用',
+		),
+		'no_access' => '你无权访问 %s',
+		'not_enabled' => '%s 未启用',
+		'not_found' => '%s 不存在',
+	),
+	'import_export' => array(
+		'export_no_zip_extension' => '服务器未启用 ZIP 扩展。请尝试一个一个导出文件。',
+		'feeds_imported' => '你的 RSS 源已导入,即将更新',
+		'feeds_imported_with_errors' => '你的 RSS 源已导入,但发生错误',
+		'file_cannot_be_uploaded' => '文件未能上传!',
+		'no_zip_extension' => '服务器未启用 ZIP 扩展。',
+		'zip_error' => '导入 ZIP 文件时出错',
+	),
+	'sub' => array(
+		'actualize' => '获取',
+		'category' => array(
+			'created' => '分类 %s 已创建。',
+			'deleted' => '分类已删除。',
+			'emptied' => '分类已清空。',
+			'error' => '分类更新失败。',
+			'name_exists' => '分类名已存在。',
+			'no_id' => '你必须明确分类 ID',
+			'no_name' => '分类名不能为空。',
+			'not_delete_default' => '你不能删除默认分类!',
+			'not_exist' => '分类不存在!',
+			'over_max' => '你已达到分类数限制 (%d)',
+			'updated' => '分类已更新。',
+		),
+		'feed' => array(
+			'actualized' => '<em>%s</em> 已更新',
+			'actualizeds' => 'RSS 源已更新',
+			'added' => 'RSS 源 <em>%s</em> 已添加',
+			'already_subscribed' => '你已订阅 <em>%s</em>',
+			'deleted' => 'RSS 源已删除',
+			'error' => 'RSS 源更新失败',
+			'internal_problem' => 'RSS 源添加失败。<a href="%s">检查 FressRSS 日志</a> 查看详情。',
+			'invalid_url' => 'URL <em>%s</em> 无效',
+			'marked_read' => 'RSS 源已被设为已读',
+			'n_actualized' => '%d 个 RSS 源已更新',
+			'n_entries_deleted' => '%d 篇文章已删除',
+			'no_refresh' => '没有可刷新的 RSS 源…',
+			'not_added' => '<em>%s</em> 添加失败',
+			'over_max' => '你已达到 RSS 源数限制 (%d)',
+			'updated' => 'RSS 源已更新',
+		),
+		'purge_completed' => '清除完成 (%d 篇文章已删除)',
+	),
+	'update' => array(
+		'can_apply' => 'FreshRSS 将更新到 <strong>版本 %s</strong>.',
+		'error' => '更新出错:%s',
+		'file_is_nok' => '请检查 <em>%s</em> 目录权限。HTTP 服务器必须有其写入权限。',
+		'finished' => '更新完成!',
+		'none' => '没有可用更新',
+		'server_not_found' => '找不到更新服务器 [%s]',
+	),
+	'user' => array(
+		'created' => array(
+			'_' => '用户 %s 已创建',
+			'error' => '用户 %s 创建失败',
+		),
+		'deleted' => array(
+			'_' => '用户 %s 已删除',
+			'error' => '用户 %s 删除失败',
+		),
+	),
+	'profile' => array(
+		'error' => '你的帐户修改失败',
+		'updated' => '你的帐户已修改',
+	),
+);

+ 185 - 0
app/i18n/zh-cn/gen.php

@@ -0,0 +1,185 @@
+<?php
+
+return array(
+	'action' => array(
+		'actualize' => '获取',
+		'back_to_rss_feeds' => '← 返回',
+		'cancel' => '取消',
+		'create' => '创建',
+		'disable' => '禁用',
+		'empty' => '清空',
+		'enable' => '启用',
+		'export' => '导出',
+		'filter' => '过滤器',
+		'import' => '导入',
+		'manage' => '管理',
+		'mark_read' => '设为已读',
+		'mark_favorite' => '加入收藏',
+		'remove' => '删除',
+		'see_website' => '查看网站',
+		'submit' => '提交',
+		'truncate' => '删除所有文章',
+	),
+	'auth' => array(
+		'email' => 'Email 地址',
+		'keep_logged_in' => '自动登录<small>(%s 天)</small>',
+		'login' => '登录',
+		'logout' => '登出',
+		'password' => array(
+			'_' => '密码',
+			'format' => '<small>至少 7 个字符</small>',
+		),
+		'registration' => array(
+			'_' => '新账户',
+			'ask' => '创建新账户?',
+			'title' => '账户创建',
+		),
+		'reset' => '认证重置',
+		'username' => array(
+			'_' => '用户名',
+			'admin' => '管理员用户名',
+			'format' => '<small>最大 16 个数字或字母</small>',
+		),
+	),
+	'date' => array(
+		'Apr' => '\\A\\p\\r\\i\\l',
+		'Aug' => '\\A\\u\\g\\u\\s\\t',
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',
+		'Jul' => '\\J\\u\\l\\y',
+		'Jun' => '\\J\\u\\n\\e',
+		'Mar' => '\\M\\a\\r\\c\\h',
+		'May' => '\\M\\a\\y',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
+		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
+		'apr' => '四月',
+		'april' => '四月',
+		'aug' => '八月',
+		'august' => '八月',
+		'before_yesterday' => '昨天以前',
+		'dec' => '十二月',
+		'december' => '十二月',
+		'feb' => '二月',
+		'february' => '二月',
+		'format_date' => 'Y\\年n\\月j\\日',
+		'format_date_hour' => 'Y\\年n\\月j\\日  H\\:i',
+		'fri' => '周五',
+		'jan' => '一月',
+		'january' => '一月',
+		'jul' => '七月',
+		'july' => '七月',
+		'jun' => '六月',
+		'june' => '六月',
+		'last_3_month' => '最近三个月',
+		'last_6_month' => '最近六个月',
+		'last_month' => '上月',
+		'last_week' => '上周',
+		'last_year' => '去年',
+		'mar' => '三月',
+		'march' => '三月',
+		'may' => '五月',
+		'mon' => '周一',
+		'month' => '个月',
+		'nov' => '十一月',
+		'november' => '十一月',
+		'oct' => '十月',
+		'october' => '十月',
+		'sat' => '周日',
+		'sep' => '九月',
+		'september' => '九月',
+		'sun' => '周日',
+		'thu' => '周四',
+		'today' => '今天',
+		'tue' => '周二',
+		'wed' => '周三',
+		'yesterday' => '昨天',
+	),
+	'freshrss' => array(
+		'_' => 'FreshRSS',
+		'about' => '关于 FreshRSS',
+	),
+	'js' => array(
+		'category_empty' => '清空分类',
+		'confirm_action' => '你确定要执行此操作吗?这将不可撤销!',
+		'confirm_action_feed_cat' => '你确定要执行此操作吗?你将丢失相关的收藏和自定义查询。这将不可撤销!',
+		'feedback' => array(
+			'body_new_articles' => 'FreshRSS 中有 %%d 篇文章等待阅读。',
+			'request_failed' => '请求失败,这可能是因为网络连接问题。',
+			'title_new_articles' => 'FreshRSS: 新文章!',
+		),
+		'new_article' => '发现新文章,点击刷新页面。',
+		'should_be_activated' => 'JavaScript 必须启用',
+	),
+	'lang' => array(
+		'cz' => 'Čeština',
+		'de' => 'Deutsch',
+		'en' => 'English1',
+		'fr' => 'Français',
+		'it' => 'Italiano1',
+		'nl' => 'Nederlands',
+		'ru' => 'Русский',
+		'tr' => 'Türkçe',
+		'zh-cn' => '简体中文'
+	),
+	'menu' => array(
+		'about' => '关于',
+		'admin' => '管理',
+		'archiving' => '存档',
+		'authentication' => '认证',
+		'check_install' => '环境检查',
+		'configuration' => '配置',
+		'display' => '显示',
+		'extensions' => '扩展',
+		'logs' => '日志',
+		'queries' => '自定义查询',
+		'reading' => '阅读',
+		'search' => '搜索内容或#标签',
+		'sharing' => '分享',
+		'shortcuts' => '快捷键',
+		'stats' => '统计',
+		'system' => '系统配置',
+		'update' => '更新',
+		'user_management' => '用户管理',
+		'user_profile' => '用户帐户',
+	),
+	'pagination' => array(
+		'first' => '第一页',
+		'last' => '最后一页',
+		'load_more' => '载入更多文章',
+		'mark_all_read' => '全部设为已读',
+		'next' => '下一页',
+		'nothing_to_load' => '没有更多文章了',
+		'previous' => '上一页',
+	),
+	'share' => array(
+		'blogotext' => 'Blogotext',
+		'diaspora' => 'Diaspora*',
+		'email' => 'Email',
+		'facebook' => 'Facebook',
+		'g+' => 'Google+',
+		'movim' => 'Movim',
+		'print' => 'Print',
+		'shaarli' => 'Shaarli',
+		'twitter' => 'Twitter',
+		'wallabag' => 'wallabag v1',
+		'wallabagv2' => 'wallabag v2',
+		'jdh' => 'Journal du hacker',
+		'Known' => 'Known based sites',
+		'gnusocial' => 'GNU social',
+	),
+	'short' => array(
+		'attention' => '警告!',
+		'blank_to_disable' => '留空以禁用',
+		'by_author' => 'By <em>%s</em>',
+		'by_default' => '默认',
+		'damn' => '错误!',
+		'default_category' => '未分类',
+		'no' => '否',
+		'not_applicable' => '不可用',
+		'ok' => '正常!',
+		'or' => '或',
+		'yes' => '是',
+	),
+);

+ 61 - 0
app/i18n/zh-cn/index.php

@@ -0,0 +1,61 @@
+<?php
+
+return array(
+	'about' => array(
+		'_' => '关于',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'bugs_reports' => 'Bug 报告',
+		'credits' => '致谢',
+		'credits_content' => '某些设计元素来自于 <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> ,尽管 FreshRSS 并没有使用此框架。<a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">图标</a> 来自于 <a href="https://www.gnome.org/">GNOME 项目</a>。<em>Open Sans</em> 字体出自 <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a> 之手。FreshRSS 基于 PHP 框架 <a href="https://github.com/marienfressinaud/MINZ">Minz</a>。',
+		'freshrss_description' => 'FreshRSS 是一个自托管的 RSS 聚合服务,类似于 <a href="http://tontof.net/kriss/feed/">Kriss Feed</a> 或 <a href="http://projet.idleman.fr/leed/">Leed</a>。 它不仅轻快又易用,而且强大又易于配置。',
+		'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">Github Issues</a>',
+		'license' => '授权',
+		'project_website' => '项目网站',
+		'title' => '关于',
+		'version' => '版本',
+		'website' => '网站',
+	),
+	'feed' => array(
+		'add' => '你可以添加一些 RSS 源。',
+		'empty' => '暂时没有文章可显示。',
+		'rss_of' => '%s 的 RSS 源',
+		'title' => '首页',
+		'title_global' => '全屏视图',
+		'title_fav' => '收藏',
+	),
+	'log' => array(
+		'_' => '日志',
+		'clear' => '清除日志',
+		'empty' => '日志文件为空',
+		'title' => '日志',
+	),
+	'menu' => array(
+		'about' => '关于 FreshRSS',
+		'add_query' => '添加查询',
+		'before_one_day' => '一天前',
+		'before_one_week' => '一周前',
+		'favorites' => '收藏 (%s)',
+		'global_view' => '全屏视图',
+		'main_stream' => '首页',
+		'mark_all_read' => '全部设为已读',
+		'mark_cat_read' => '此分类设为已读',
+		'mark_feed_read' => '此源设为已读',
+		'newer_first' => '由新到旧',
+		'non-starred' => '不显示收藏',
+		'normal_view' => '普通视图',
+		'older_first' => '由旧到新',
+		'queries' => '自定义查询',
+		'read' => '只显示已读',
+		'reader_view' => '阅读视图',
+		'rss_view' => 'RSS 源',
+		'search_short' => '搜索',
+		'starred' => '只显示收藏',
+		'stats' => '统计',
+		'subscription' => '订阅管理',
+		'unread' => '只显示未读',
+	),
+	'share' => '分享',
+	'tag' => array(
+		'related' => '相关标签',
+	),
+);

+ 119 - 0
app/i18n/zh-cn/install.php

@@ -0,0 +1,119 @@
+<?php
+
+return array(
+	'action' => array(
+		'finish' => '完成安装',
+		'fix_errors_before' => '请在继续下一步前修复错误。',
+		'keep_install' => '保留以前配置',
+		'next_step' => '下一步',
+		'reinstall' => '重新安装 FreshRSS',
+	),
+	'auth' => array(
+		'form' => 'Web form (传统方式, 需要 JavaScript)',
+		'http' => 'HTTP (面向启用 HTTPS 的高级用户)',
+		'none' => '无 (危险)',
+		'password_form' => '密码<br /><small>(用于 Web-form 登录方式)</small>',
+		'password_format' => '至少 7 个字符',
+		'type' => '认证方式',
+	),
+	'bdd' => array(
+		'_' => '数据库',
+		'conf' => array(
+			'_' => '数据库配置',
+			'ko' => '请验证你的数据库信息。',
+			'ok' => '数据库配置已保存。',
+		),
+		'host' => '主机',
+		'prefix' => '表前缀',
+		'password' => '密码',
+		'type' => '数据库类型',
+		'username' => '用户名',
+	),
+	'check' => array(
+		'_' => '检查',
+		'already_installed' => '我们检测到 FreshRSS 已经安装!',
+		'cache' => array(
+			'nok' => '请检查 <em>./data/cache</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'cache 目录权限正常。',
+		),
+		'ctype' => array(
+			'nok' => '找不到字符类型检测库 (php-ctype) 。',
+			'ok' => '你已有字符类型检测库 (ctype) 。',
+		),
+		'curl' => array(
+			'nok' => '找不到 cURL 库 (php-curl package) 。',
+			'ok' => '你已有 cURL 库。',
+		),
+		'data' => array(
+			'nok' => '请检查 <em>./data</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'data 目录权限正常。',
+		),
+		'dom' => array(
+			'nok' => '找不到用于浏览 DOM 的库 (php-xml) 。',
+			'ok' => '你已有用于浏览 DOM 的库。',
+		),
+		'favicons' => array(
+			'nok' => '请检查 <em>./data/favicons</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'favicons 目录权限正常。',
+		),
+		'fileinfo' => array(
+			'nok' => '找不到 PHP fileinfo 库 (fileinfo) 。',
+			'ok' => '你已有 fileinfo 库。',
+		),
+		'http_referer' => array(
+			'nok' => '请检查你是否修改了 HTTP REFERER。',
+			'ok' => '你的 HTTP REFERER 已知且与服务器一致。',
+		),
+		'json' => array(
+			'nok' => '找不到推荐的 JSON 解析库。',
+			'ok' => '你已有推荐的 JSON 解析库。',
+		),
+		'minz' => array(
+			'nok' => '找不到 Minz 框架。',
+			'ok' => '你已有 Minz 框架。',
+		),
+		'pcre' => array(
+			'nok' => '找不到正则表达式解析库 (php-pcre) 。',
+			'ok' => '你已有正则表达式解析库 (PCRE) 。',
+		),
+		'pdo' => array(
+			'nok' => '找不到 PDO 或支持的驱动 (pdo_mysql, pdo_sqlite, pdo_pgsql) 。',
+			'ok' => '你已有 PDO 和支持的至少一种驱动 (pdo_mysql, pdo_sqlite, pdo_pgsql) 。',
+		),
+		'php' => array(
+			'nok' => '你的 PHP 版本为 %s,但 FreshRSS 最低需要 %s。',
+			'ok' => '你的 PHP 版本为 %s,与 FreshRSS 兼容。',
+		),
+		'users' => array(
+			'nok' => '请检查 <em>./data/users</em> 目录权限。HTTP 服务器必须有其写入权限。',
+			'ok' => 'users 目录权限正常。',
+		),
+		'xml' => array(
+			'nok' => '找不到用于 XML 解析库。',
+			'ok' => '你已有 XML 解析库。',
+		),
+	),
+	'conf' => array(
+		'_' => '常规配置',
+		'ok' => '常规配置已保存。',
+	),
+	'congratulations' => '恭喜!',
+	'default_user' => '默认用户名 <small>(最大 16 个数字或字母)</small>',
+	'delete_articles_after' => '保留文章',
+	'fix_errors_before' => '请在继续下一步前修复错误。',
+	'javascript_is_better' => '启用 JavaScript 会使 FreshRSS 工作得更好',
+	'js' => array(
+		'confirm_reinstall' => '重新安装 FreshRSS 将会重置之前的配置。你确定要继续吗?',
+	),
+	'language' => array(
+		'_' => '语言',
+		'choose' => '为 FreshRSS 选择语言',
+		'defined' => '语言已指定。',
+	),
+	'not_deleted' => '出错!你必须手动删除文件 <em>%s</em>。',
+	'ok' => '安装成功。',
+	'step' => '步骤 %d',
+	'steps' => '步骤',
+	'title' => '安装 FreshRSS',
+	'this_is_the_end' => '最后一步',
+);

+ 62 - 0
app/i18n/zh-cn/sub.php

@@ -0,0 +1,62 @@
+<?php
+
+return array(
+	'category' => array(
+		'_' => '分类',
+		'add' => '添加分类',
+		'empty' => '空分类',
+		'new' => '新分类',
+	),
+	'feed' => array(
+		'add' => '添加 RSS 源',
+		'advanced' => '高级',
+		'archiving' => '存档',
+		'auth' => array(
+			'configuration' => '认证',
+			'help' => '连接启用 HTTP 认证的 RSS 源',
+			'http' => 'HTTP 认证',
+			'password' => 'HTTP 密码',
+			'username' => 'HTTP 用户名',
+		),
+		'css_help' => '获取全文(注意,会耗费更多时间!)',
+		'css_path' => '原网站中文章的 CSS 路径',
+		'description' => '描述',
+		'empty' => '此源为空。请确认它是否正常更新。',
+		'error' => '此源遇到一些问题。请确认它是否可访问后重试。',
+		'in_main_stream' => '在首页中显示',
+		'informations' => '信息',
+		'keep_history' => '至少保存的文章数',
+		'moved_category_deleted' => '删除分类时,其中的 RSS 源会自动归类到<em>%s</em>。',
+		'no_selected' => '未选择 RSS 源。',
+		'number_entries' => '%d 篇文章',
+		'stats' => '统计',
+		'think_to_add' => '你可以添加一些 RSS 源。',
+		'title' => '标题',
+		'title_add' => '添加 RSS 源',
+		'ttl' => '最小自动更新时间',
+		'url' => '源 URL',
+		'validator' => '检查 RSS 源有效性',
+		'website' => '网站 URL',
+		'pubsubhubbub' => 'PubSubHubbub 即时通知',
+	),
+	'import_export' => array(
+		'export' => '导出',
+		'export_opml' => '导出 RSS 源列表 (OPML)',
+		'export_starred' => '导出你的收藏',
+		'feed_list' => '%s 文章列表',
+		'file_to_import' => '需要导入的文件<br />(OPML, JSON 或 ZIP)',
+		'file_to_import_no_zip' => '需要导入的文件<br />(OPML 或 JSON)',
+		'import' => '导入',
+		'starred_list' => '收藏文章列表',
+		'title' => '导入/导出',
+	),
+	'menu' => array(
+		'bookmark' => '订阅 (FreshRSS 书签)',
+		'import_export' => '导入/导出',
+		'subscription_management' => '订阅管理',
+	),
+	'title' => array(
+		'_' => '订阅管理',
+		'feed_management' => 'RSS 源管理',
+	),
+);

+ 52 - 0
cli/README.md

@@ -89,3 +89,55 @@ Example to get the number of feeds of a given user:
 ```sh
 ./cli/user-info.php --user alex | cut -f6
 ```
+
+
+# Install and updates
+
+## Using git
+
+If you manage FreshRSS via command line, then installing and updating FreshRSS can be done via git:
+
+```sh
+# If your local user does not have write access, prefix all commands by sudo:
+sudo ...
+
+# Install FreshRSS
+cd /usr/share/
+git clone https://github.com/FreshRSS/FreshRSS.git
+
+# Perform all commands below in your FreshRSS directory:
+cd /usr/share/FreshRSS
+
+# Use the development version of FreshRSS
+git checkout -b dev origin/dev
+
+# Check out a specific version of FreshRSS
+# See release names on https://github.com/FreshRSS/FreshRSS/releases
+# You will then need to manually change version
+# or checkout master or dev branch to get new versions
+git checkout 1.7.0
+
+# Verify what branch is used
+git branch
+
+# Check whether there is a new version of FreshRSS,
+# assuming you are on the /master or /dev branch
+git fetch --all
+git status
+
+# Discard manual changes (do a backup before)
+git reset --hard
+# Then re-delete the file forcing the setup wizard
+rm data/do-install.txt
+
+# Delete manual additions (do a backup before)
+git clean -f -d
+
+# Update to a newer version of FreshRSS,
+# assuming you are on the /master or /dev branch
+git pull
+
+# Set the rights so that your Web server can access the files
+# (Example for Debian / Ubuntu)
+chown -R :www-data . && chmod -R g+r . && chmod -R g+w ./data/
+```

+ 1 - 1
p/themes/BlueLagoon/BlueLagoon.css

@@ -10,7 +10,7 @@
 /*============*/
 html, body {
 	height: 100%;
-	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", sans-serif;
+	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", "PingFang SC", "Microsoft YaHei", sans-serif;
 	background: #fafafa;
 	font-size: 92%;
 }

+ 1 - 1
p/themes/Dark/dark.css

@@ -10,7 +10,7 @@
 /*============*/
 html, body {
 	height: 100%;
-	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", sans-serif;
+	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", "PingFang SC", "Microsoft YaHei", sans-serif;
 	background: #1c1c1c;
 	color: #888;
 }

+ 1 - 1
p/themes/Flat/flat.css

@@ -10,7 +10,7 @@
 /*============*/
 html, body {
 	height: 100%;
-	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", sans-serif;
+	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", "PingFang SC", "Microsoft YaHei", sans-serif;
 	background: #fafafa;
 }
 

+ 1 - 1
p/themes/Origine-compact/origine-compact.css

@@ -10,7 +10,7 @@
 /*============*/
 html, body {
 	height: 100%;
-	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", sans-serif;
+	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", "PingFang SC", "Microsoft YaHei", sans-serif;
 	background: #fafafa;
 }
 

+ 1 - 1
p/themes/Origine/origine.css

@@ -10,7 +10,7 @@
 /*============*/
 html, body {
 	height: 100%;
-	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", sans-serif;
+	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", "PingFang SC", "Microsoft YaHei", sans-serif;
 	background: #fafafa;
 }
 

+ 1 - 1
p/themes/Pafat/pafat.css

@@ -10,7 +10,7 @@
 /*============*/
 html, body {
 	height: 100%;
-	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", sans-serif;
+	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", "PingFang SC", "Microsoft YaHei", sans-serif;
 	background: #fafafa;
 	color : #666;
 }

+ 1 - 1
p/themes/Screwdriver/screwdriver.css

@@ -10,7 +10,7 @@
 /*============*/
 html, body {
 	height: 100%;
-	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", sans-serif;
+	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", "PingFang SC", "Microsoft YaHei", sans-serif;
 	background: #fafafa;
 	font-size: 92%;
 }

+ 1 - 1
p/themes/base-theme/base.css

@@ -10,7 +10,7 @@
 /*============*/
 html, body {
 	height: 100%;
-	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", sans-serif;
+	font-family: "OpenSans", "Cantarell", "Helvetica", "Arial", "PingFang SC", "Microsoft YaHei", sans-serif;
 }
 
 /*=== Links */