Ver código fonte

Merge pull request #2186 from FreshRSS/dev

FreshRSS 1.13.0
Alexandre Alapetite 7 anos atrás
pai
commit
f0a359619f
100 arquivos alterados com 2891 adições e 1372 exclusões
  1. 3 3
      .dockerignore
  2. 48 0
      CHANGELOG.md
  3. 3 0
      CREDITS.md
  4. 160 62
      Docker/README.md
  5. 47 31
      LICENSE.txt
  6. 58 43
      README.md
  7. 2 0
      app/Controllers/configureController.php
  8. 6 6
      app/Controllers/feedController.php
  9. 141 27
      app/Controllers/importExportController.php
  10. 2 0
      app/Controllers/subscriptionController.php
  11. 7 5
      app/Models/Auth.php
  12. 8 0
      app/Models/BooleanSearch.php
  13. 3 0
      app/Models/ConfigurationSetter.php
  14. 11 2
      app/Models/EntryDAO.php
  15. 11 10
      app/Models/Feed.php
  16. 7 1
      app/Models/FeedDAO.php
  17. 8 0
      app/Models/Search.php
  18. 1 1
      app/Models/TagDAO.php
  19. 21 17
      app/i18n/cz/admin.php
  20. 28 25
      app/i18n/cz/conf.php
  21. 9 9
      app/i18n/cz/feedback.php
  22. 17 14
      app/i18n/cz/gen.php
  23. 3 3
      app/i18n/cz/index.php
  24. 4 4
      app/i18n/cz/install.php
  25. 23 16
      app/i18n/cz/sub.php
  26. 12 8
      app/i18n/de/admin.php
  27. 19 16
      app/i18n/de/conf.php
  28. 5 5
      app/i18n/de/feedback.php
  29. 13 11
      app/i18n/de/gen.php
  30. 2 2
      app/i18n/de/index.php
  31. 1 1
      app/i18n/de/install.php
  32. 8 1
      app/i18n/de/sub.php
  33. 10 6
      app/i18n/en/admin.php
  34. 25 19
      app/i18n/en/conf.php
  35. 4 4
      app/i18n/en/feedback.php
  36. 13 11
      app/i18n/en/gen.php
  37. 1 1
      app/i18n/en/index.php
  38. 3 3
      app/i18n/en/install.php
  39. 8 1
      app/i18n/en/sub.php
  40. 16 12
      app/i18n/es/admin.php
  41. 28 25
      app/i18n/es/conf.php
  42. 9 9
      app/i18n/es/feedback.php
  43. 15 13
      app/i18n/es/gen.php
  44. 3 3
      app/i18n/es/index.php
  45. 3 3
      app/i18n/es/install.php
  46. 28 10
      app/i18n/es/sub.php
  47. 10 6
      app/i18n/fr/admin.php
  48. 18 15
      app/i18n/fr/conf.php
  49. 4 4
      app/i18n/fr/feedback.php
  50. 14 12
      app/i18n/fr/gen.php
  51. 8 1
      app/i18n/fr/sub.php
  52. 70 66
      app/i18n/he/admin.php
  53. 32 26
      app/i18n/he/conf.php
  54. 24 25
      app/i18n/he/feedback.php
  55. 32 30
      app/i18n/he/gen.php
  56. 3 3
      app/i18n/he/index.php
  57. 28 20
      app/i18n/he/install.php
  58. 25 17
      app/i18n/he/sub.php
  59. 17 13
      app/i18n/it/admin.php
  60. 27 24
      app/i18n/it/conf.php
  61. 9 9
      app/i18n/it/feedback.php
  62. 14 12
      app/i18n/it/gen.php
  63. 3 3
      app/i18n/it/index.php
  64. 3 4
      app/i18n/it/install.php
  65. 24 17
      app/i18n/it/sub.php
  66. 12 8
      app/i18n/kr/admin.php
  67. 19 16
      app/i18n/kr/conf.php
  68. 6 6
      app/i18n/kr/feedback.php
  69. 14 12
      app/i18n/kr/gen.php
  70. 3 3
      app/i18n/kr/index.php
  71. 3 3
      app/i18n/kr/install.php
  72. 9 2
      app/i18n/kr/sub.php
  73. 10 11
      app/i18n/nl/admin.php
  74. 18 15
      app/i18n/nl/conf.php
  75. 4 5
      app/i18n/nl/feedback.php
  76. 14 12
      app/i18n/nl/gen.php
  77. 2 1
      app/i18n/nl/index.php
  78. 1 1
      app/i18n/nl/install.php
  79. 9 2
      app/i18n/nl/sub.php
  80. 199 0
      app/i18n/oc/admin.php
  81. 187 0
      app/i18n/oc/conf.php
  82. 116 0
      app/i18n/oc/feedback.php
  83. 196 0
      app/i18n/oc/gen.php
  84. 63 0
      app/i18n/oc/index.php
  85. 123 0
      app/i18n/oc/install.php
  86. 93 0
      app/i18n/oc/sub.php
  87. 16 12
      app/i18n/pt-br/admin.php
  88. 28 25
      app/i18n/pt-br/conf.php
  89. 9 9
      app/i18n/pt-br/feedback.php
  90. 16 13
      app/i18n/pt-br/gen.php
  91. 3 2
      app/i18n/pt-br/index.php
  92. 3 3
      app/i18n/pt-br/install.php
  93. 20 13
      app/i18n/pt-br/sub.php
  94. 16 12
      app/i18n/ru/admin.php
  95. 134 131
      app/i18n/ru/conf.php
  96. 72 72
      app/i18n/ru/feedback.php
  97. 135 133
      app/i18n/ru/gen.php
  98. 36 35
      app/i18n/ru/index.php
  99. 11 3
      app/i18n/ru/install.php
  100. 69 62
      app/i18n/ru/sub.php

+ 3 - 3
.dockerignore

@@ -1,3 +1,3 @@
-*/.git
-*/data
-*/docs
+**/.git/
+**/data/
+**/docs/

+ 48 - 0
CHANGELOG.md

@@ -1,5 +1,52 @@
 # FreshRSS changelog
 # FreshRSS changelog
 
 
+## 2018-12-22 FreshRSS 1.13.0
+
+* API
+	* Improvements to the Google Reader API [#2093](https://github.com/FreshRSS/FreshRSS/pull/2093)
+		* Support for [Vienna RSS](http://www.vienna-rss.com/) (client for Mac OS X) [#2091](https://github.com/FreshRSS/FreshRSS/issues/2091)
+	* Contributions to WebSub in third-party systems to support instant push notifications
+		from [Mastodon](https://joinmastodon.org) 2.6.2+ and [Friendica](https://friendi.ca) 2018.12+
+		[#mastodon/9302](https://github.com/tootsuite/mastodon/pull/9302), [#friendica/6137](https://github.com/friendica/friendica/pull/6137)
+		* Rename the PubSubHubbub protocol to use the new standard [WebSub](https://www.w3.org/TR/websub/) name [#2184](https://github.com/FreshRSS/FreshRSS/pull/2184)
+* Features
+	* Ability to import XML files exported from Tiny-Tiny-RSS [#2079](https://github.com/FreshRSS/FreshRSS/issues/2079)
+	* Ability to show all the feeds that have a warning [#2146](https://github.com/FreshRSS/FreshRSS/issues/2146)
+	* Share with Pinboard [#1972](https://github.com/FreshRSS/FreshRSS/issues/1972)
+* UI
+	* Reworked the scrolling of the categories/feeds sidebar [#2117](https://github.com/FreshRSS/FreshRSS/pull/2117)
+		* Native styled scrollbars in Firefox 64+, Chrome.
+	* Show collapsed sidebar in the reader mode [#2169](https://github.com/FreshRSS/FreshRSS/issues/2169)
+	* New shortcuts to move to previous/next article without opening it [#1767](https://github.com/FreshRSS/FreshRSS/pull/1767)
+	* Fix regression from 1.12.0 preventing from closing an article [#2085](https://github.com/FreshRSS/FreshRSS/issues/2085)
+	* Improvements of the Swage theme [#2088](https://github.com/FreshRSS/FreshRSS/pull/2088), [#2094](https://github.com/FreshRSS/FreshRSS/pull/2094)
+	* Many style improvements [#2108](https://github.com/FreshRSS/FreshRSS/pull/2108), [#2115](https://github.com/FreshRSS/FreshRSS/issues/2115),
+		[#1620](https://github.com/FreshRSS/FreshRSS/issues/1620), [#2089](https://github.com/FreshRSS/FreshRSS/pull/2089),
+		[#2122](https://github.com/FreshRSS/FreshRSS/pull/2122), [#2161](https://github.com/FreshRSS/FreshRSS/pull/2161)
+* Deployment
+	* Support for `HTTP_X_FORWARDED_PREFIX` to ease the use of reverse proxies [#2191](https://github.com/FreshRSS/FreshRSS/pull/2191)
+		* Updated Docker + Træfik + Let’s Encrypt deployment guide [#2189](https://github.com/FreshRSS/FreshRSS/pull/2189)
+	* Docker image updated to Alpine 3.8.2 with PHP 7.2.13 and Apache 2.4.35
+	* Fix `.dockerignore` [#2195](https://github.com/FreshRSS/FreshRSS/pull/2195)
+* I18n
+	* Occitan [#2110](https://github.com/FreshRSS/FreshRSS/pull/2110)
+* SimplePie
+	* Update to SimplePie 1.5.2 [#2136](https://github.com/FreshRSS/FreshRSS/pull/2136)
+		* Fix some sanitizing in authors / tags
+	* Strip embedded SVG images for now [#2135](https://github.com/FreshRSS/FreshRSS/pull/2135)
+* Security
+	* Fix HTML injections reported by [Netsparker](https://www.netsparker.com) [#2121](https://github.com/FreshRSS/FreshRSS/issues/2121)
+* Bug fixing
+	* Fix warning in `tempnam()` with PHP 7.1+ affecting ZIP export [#2134](https://github.com/FreshRSS/FreshRSS/pull/2134)
+	* Fix print for views with unfolded articles [#2130](https://github.com/FreshRSS/FreshRSS/issues/2130)
+	* Fix notifications in reader view [#1407](https://github.com/FreshRSS/FreshRSS/issues/1407)
+	* Fix sharing with Movim [#1781](https://github.com/FreshRSS/FreshRSS/issues/1781)
+* Misc.
+	* Add username in configuration menu and exported files [#2133](https://github.com/FreshRSS/FreshRSS/pull/2133)
+	* New option to set the duration of the cookie session [#2137](https://github.com/FreshRSS/FreshRSS/pull/2137)
+	* Add [donation option via Liberapay](https://liberapay.com/FreshRSS/) [#1694](https://github.com/FreshRSS/FreshRSS/issues/1694)
+
+
 ## 2018-10-28 FreshRSS 1.12.0
 ## 2018-10-28 FreshRSS 1.12.0
 
 
 * Features
 * Features
@@ -25,6 +72,7 @@
 * Deployment
 * Deployment
 	* Fix Docker bug with some cron values [#2032](https://github.com/FreshRSS/FreshRSS/pull/2032)
 	* Fix Docker bug with some cron values [#2032](https://github.com/FreshRSS/FreshRSS/pull/2032)
 	* Perform `git clean -f -d -f` (removes unknown files and folders) before git auto-update method [#2036](https://github.com/FreshRSS/FreshRSS/pull/2036)
 	* Perform `git clean -f -d -f` (removes unknown files and folders) before git auto-update method [#2036](https://github.com/FreshRSS/FreshRSS/pull/2036)
+	* Docker image updated to Alpine 3.8.1 with PHP 7.2.8 and Apache 2.4.34
 * Bug fixing
 * Bug fixing
 	* Make article GUIDs case-sensitive also with MySQL [#2077](https://github.com/FreshRSS/FreshRSS/issues/2077)
 	* Make article GUIDs case-sensitive also with MySQL [#2077](https://github.com/FreshRSS/FreshRSS/issues/2077)
 	* Ask confirmation for important configuration actions [#2048](https://github.com/FreshRSS/FreshRSS/pull/2048)
 	* Ask confirmation for important configuration actions [#2048](https://github.com/FreshRSS/FreshRSS/pull/2048)

+ 3 - 0
CREDITS.md

@@ -44,6 +44,7 @@ People are sorted by name so please keep this order.
 * [MSZ](https://github.com/mszkb): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=mszkb)
 * [MSZ](https://github.com/mszkb): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=mszkb)
 * [Nico B](https://github.com/youknow0): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:youknow0)
 * [Nico B](https://github.com/youknow0): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:youknow0)
 * [Nicolas Elie](https://github.com/nicolaselie): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=nicolaselie)
 * [Nicolas Elie](https://github.com/nicolaselie): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=nicolaselie)
+* [Nicolas Frandeboeuf](https://github.com/nicofrand): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=nicofrand), [Web](https://nicofrand.ey)
 * [Nicolas Lœuillet](https://github.com/nicosomb): [contributions](https://github.com/FreshRSS/documentation/commits?author=nicosomb), [Web](http://www.loeuillet.org/)
 * [Nicolas Lœuillet](https://github.com/nicosomb): [contributions](https://github.com/FreshRSS/documentation/commits?author=nicosomb), [Web](http://www.loeuillet.org/)
 * [Nicola Spanti](https://github.com/RyDroid): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:RyDroid), [Web](http://www.nicola-spanti.info/)
 * [Nicola Spanti](https://github.com/RyDroid): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:RyDroid), [Web](http://www.nicola-spanti.info/)
 * [Olivier Dossmann](https://github.com/blankoworld): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=blankoworld), [Web](https://olivier.dossmann.net)
 * [Olivier Dossmann](https://github.com/blankoworld): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=blankoworld), [Web](https://olivier.dossmann.net)
@@ -54,12 +55,14 @@ People are sorted by name so please keep this order.
 * [primaeval](https://github.com/primaeval): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:primaeval)
 * [primaeval](https://github.com/primaeval): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:primaeval)
 * [purexo](https://github.com/purexo): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:purexo), [Web](https://purexo.mom/)
 * [purexo](https://github.com/purexo): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:purexo), [Web](https://purexo.mom/)
 * [Quentin Dufour](https://github.com/superboum): [contributions](https://github.com/FreshRSS/documentation/commits?author=superboum), [Web](http://quentin.dufour.io/)
 * [Quentin Dufour](https://github.com/superboum): [contributions](https://github.com/FreshRSS/documentation/commits?author=superboum), [Web](http://quentin.dufour.io/)
+* [Quentin Pagès](https://github.com/Quenty31): [contributions](https://github.com/FreshRSS/documentation/commits?author=Quenty31)
 * [Ramón Cutanda](https://github.com/rcutanda): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:rcutanda)
 * [Ramón Cutanda](https://github.com/rcutanda): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:rcutanda)
 * [romibi](https://github.com/romibi): [contributions](https://github.com/FreshRSS/FreshRSS/commits/dev?author=romibi)
 * [romibi](https://github.com/romibi): [contributions](https://github.com/FreshRSS/FreshRSS/commits/dev?author=romibi)
 * [sirideain](https://github.com/sirideain): [contributions](https://github.com/FreshRSS/FreshRSS/commits/dev?author=sirideain)
 * [sirideain](https://github.com/sirideain): [contributions](https://github.com/FreshRSS/FreshRSS/commits/dev?author=sirideain)
 * [subic](https://github.com/subic): [contributions](https://github.com/FreshRSS/documentation/commits?author=subic)
 * [subic](https://github.com/subic): [contributions](https://github.com/FreshRSS/documentation/commits?author=subic)
 * [Tets42](https://github.com/Tets42): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=Tets42)
 * [Tets42](https://github.com/Tets42): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=Tets42)
 * [Thomas Citharel](https://github.com/tcitworld): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:tomgue), [Web](https://www.tcit.fr/)
 * [Thomas Citharel](https://github.com/tcitworld): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:tomgue), [Web](https://www.tcit.fr/)
+* [thomas-gt](https://github.com/thomas-gt): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:thomas-gt)
 * [tomgue](https://github.com/tomgue): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=tomgue)
 * [tomgue](https://github.com/tomgue): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=tomgue)
 * [Twilek-de](https://github.com/Twilek-de): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:Twilek-de)
 * [Twilek-de](https://github.com/Twilek-de): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:Twilek-de)
 * [Uncovery](https://github.com/uncovery): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:uncovery)
 * [Uncovery](https://github.com/uncovery): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:uncovery)

+ 160 - 62
Docker/README.md

@@ -1,7 +1,6 @@
 # Deploy FreshRSS with Docker
 # Deploy FreshRSS with Docker
-* See also:
-	* https://hub.docker.com/r/freshrss/freshrss/
-	* https://cloud.docker.com/app/freshrss/repository/docker/freshrss/freshrss
+* See also https://hub.docker.com/r/freshrss/freshrss/
+
 
 
 ## Install Docker
 ## Install Docker
 
 
@@ -10,9 +9,10 @@ curl -fsSL https://get.docker.com/ -o get-docker.sh
 sh get-docker.sh
 sh get-docker.sh
 ```
 ```
 
 
+
 ## Optional: Build Docker image of FreshRSS
 ## Optional: Build Docker image of FreshRSS
 Optional, as a *less recent* online image can be automatically fetched during the next step (run),
 Optional, as a *less recent* online image can be automatically fetched during the next step (run),
-but online images are not available for as many platforms as if you build yourself.
+but online images are not available for as many platforms (e.g. Raspberry Pi / ARM) as if you build yourself.
 
 
 ```sh
 ```sh
 # First time only
 # First time only
@@ -24,53 +24,111 @@ sudo docker pull alpine:3.8
 sudo docker build --tag freshrss/freshrss -f Docker/Dockerfile .
 sudo docker build --tag freshrss/freshrss -f Docker/Dockerfile .
 ```
 ```
 
 
-## Run FreshRSS
-
-Example using SQLite, built-in cron, and exposing FreshRSS on port 8080. You may have to adapt the parameters to fit your needs.
 
 
+## Create an isolated network
 ```sh
 ```sh
-# You can optionally run from the directory containing the FreshRSS source code:
-cd ./FreshRSS/
+sudo docker network create freshrss-network
+```
+
+## Recommended: use [Træfik](https://traefik.io/) reverse proxy
+It is a good idea to use a reverse proxy on your host server, providing HTTPS.
+Here is the recommended configuration using automatic [Let’s Encrypt](https://letsencrypt.org/) HTTPS certificates and with a redirection from HTTP to HTTPS. See further below for alternatives.
 
 
-# The data will be saved on the host in `./data/`
-mkdir -p ./data/
+```sh
+sudo docker volume create traefik-letsencrypt
 
 
+# Just change your e-mail address in the command below:
 sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
 sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
-  -v $(pwd)/data:/var/www/FreshRSS/data \
-  -e 'CRON_MIN=5,35' \
-  -p 8080:80 \
-  --name freshrss freshrss/freshrss
+  -v traefik-letsencrypt:/etc/traefik/acme \
+  -v /var/run/docker.sock:/var/run/docker.sock:ro \
+  --net freshrss-network \
+  -p 80:80 \
+  -p 443:443 \
+  --name traefik traefik --docker \
+  --entryPoints='Name:http Address::80 Compress:true Redirect.EntryPoint:https' \
+  --entryPoints='Name:https Address::443 Compress:true TLS TLS.MinVersion:VersionTLS12 TLS.SniStrict:true TLS.CipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA' \
+  --defaultentrypoints=http,https --keeptrailingslash=true \
+  --acme=true --acme.entrypoint=https --acme.onhostrule=true --acme.tlsChallenge \
+  --acme.storage=/etc/traefik/acme/acme.json --acme.email=you@example.net
 ```
 ```
 
 
-### Examples with external databases
+See [more information about Docker and Let’s Encrypt in Træfik](https://docs.traefik.io/user-guide/docker-and-lets-encrypt/).
 
 
-You may want to use other link methods such as Docker bridges, and use Docker volumes for the data, but here are some simple examples:
 
 
-#### MySQL
-See https://hub.docker.com/_/mysql/
+## Run FreshRSS 
+Example using the built-in refresh cron job (see further below for alternatives).
+You must first chose a domain (DNS) or sub-domain, e.g. `freshrss.example.net`.
 
 
 ```sh
 ```sh
-sudo docker run -d -v /path/to/mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=rootpass -e MYSQL_DATABASE=freshrss -e MYSQL_USER=freshrss -e MYSQL_PASSWORD=pass --name mysql mysql
+sudo docker volume create freshrss-data
+
+# Remember to replace freshrss.example.net by your server address in the command below:
 sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
 sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
-  -v $(pwd)/data:/var/www/FreshRSS/data \
-  -e 'CRON_MIN=17,47' \
-  --link mysql -p 8080:80 \
+  -v freshrss-data:/var/www/FreshRSS/data \
+  -e 'CRON_MIN=4,34' \
+  --net freshrss-network \
+  --label traefik.port=80 \
+  --label traefik.frontend.rule='Host:freshrss.example.net' \
+  --label traefik.frontend.headers.forceSTSHeader=true \
+  --label traefik.frontend.headers.STSSeconds=31536000 \
   --name freshrss freshrss/freshrss
   --name freshrss freshrss/freshrss
 ```
 ```
 
 
-#### PostgreSQL
-See https://hub.docker.com/_/postgres/
+* If you cannot have FreshRSS at the root of a dedicated domain, update the command above according to the following model:
+	`--label traefik.frontend.rule='Host:freshrss.example.net;PathPrefixStrip:/FreshRSS/' \`
+* You may remove the `--label traefik.*` lines if you do not use Træfik.
+* Add `-p 8080:80 \` if you want to expose FreshRSS locally, e.g. on port `8080`.
+
+This already works with a built-in **SQLite** database (easiest), but more powerful databases are supported:
 
 
+### [MySQL](https://hub.docker.com/_/mysql/)
 ```sh
 ```sh
-sudo docker run -d -v /path/to/pgsql-data:/var/lib/postgresql/data -e POSTGRES_DB=freshrss -e POSTGRES_USER=freshrss -e POSTGRES_PASSWORD=pass --name postgres postgres
+# If you already have a MySQL instance running, just attach it to the FreshRSS network:
+sudo docker network connect freshrss-network mysql
+
+# Otherwise, start a new MySQL instance, remembering to change the passwords:
+sudo docker volume create mysql-data
 sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
 sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
-  -v $(pwd)/data:/var/www/FreshRSS/data \
-  -e 'CRON_MIN=23,53' \
-  --link postgres -p 8080:80 \
-  --name freshrss freshrss/freshrss
+  -v mysql-data:/var/lib/mysql \
+  -e MYSQL_ROOT_PASSWORD=rootpass
+  -e MYSQL_DATABASE=freshrss \
+  -e MYSQL_USER=freshrss \
+  -e MYSQL_PASSWORD=pass \
+  --net freshrss-network \
+  --name mysql mysql
+```
+
+### [PostgreSQL](https://hub.docker.com/_/postgres/)
+```sh
+# If you already have a PostgreSQL instance running, just attach it to the FreshRSS network:
+sudo docker network connect freshrss-network postgres
+
+# Otherwise, start a new PostgreSQL instance, remembering to change the passwords:
+sudo docker volume create pgsql-data
+sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
+  -v pgsql-data:/var/lib/postgresql/data \
+  -e POSTGRES_DB=freshrss \
+  -e POSTGRES_USER=freshrss \
+  -e POSTGRES_PASSWORD=pass \
+  --net freshrss-network \
+  --name postgres postgres
 ```
 ```
 
 
-## Update
+### Complete installation
+Browse to your server https://freshrss.example.net/ to complete the installation via the FreshRSS Web interface,
+or use the command line described below.
+
+
+## Command line
+
+```sh
+sudo docker exec --user apache -it freshrss php ./cli/list-users.php
+```
+
+See the [CLI documentation](../cli/) for all the other commands.
+
+
+## How to update
 
 
 ```sh
 ```sh
 # Rebuild an image (see build section above) or get a new online version:
 # Rebuild an image (see build section above) or get a new online version:
@@ -79,35 +137,43 @@ sudo docker pull freshrss/freshrss
 sudo docker stop freshrss
 sudo docker stop freshrss
 sudo docker rename freshrss freshrss_old
 sudo docker rename freshrss freshrss_old
 # See the run section above for the full command
 # See the run section above for the full command
-sudo docker run ...
+sudo docker run ... --name freshrss freshrss/freshrss
 # If everything is working, delete the old container
 # If everything is working, delete the old container
 sudo docker rm freshrss_old
 sudo docker rm freshrss_old
 ```
 ```
 
 
-## Command line
+
+## Debugging
 
 
 ```sh
 ```sh
-sudo docker exec --user apache -it freshrss php ./cli/list-users.php
+# See FreshRSS data if you use Docker volume
+sudo docker volume inspect freshrss-data
+sudo ls /var/lib/docker/volumes/freshrss-data/_data/
+
+# See Web server logs
+sudo docker logs -f freshrss
+
+# Enter inside FreshRSS docker container
+sudo docker exec -it freshrss sh
+## See FreshRSS root inside the container
+ls /var/www/FreshRSS/
 ```
 ```
 
 
-See the [CLI documentation](../cli/) for all the other commands.
 
 
 ## Cron job to automatically refresh feeds
 ## Cron job to automatically refresh feeds
 We recommend a refresh rate of about twice per hour (see *WebSub* / *PubSubHubbub* for real-time updates).
 We recommend a refresh rate of about twice per hour (see *WebSub* / *PubSubHubbub* for real-time updates).
-There is no less than 3 options. Pick a single one.
+There are no less than 3 options. Pick a single one.
 
 
 ### Option 1) Cron inside the FreshRSS Docker image
 ### Option 1) Cron inside the FreshRSS Docker image
-Easiest, built-in solution, also used in the examples above
+Easiest, built-in solution, also used already in the examples above
 (but your Docker instance will have a second process in the background, without monitoring).
 (but your Docker instance will have a second process in the background, without monitoring).
 Just pass the environment variable `CRON_MIN` to your `docker run` command,
 Just pass the environment variable `CRON_MIN` to your `docker run` command,
 containing a valid cron minute definition such as `'13,43'` (recommended) or `'*/20'`.
 containing a valid cron minute definition such as `'13,43'` (recommended) or `'*/20'`.
 Not passing the `CRON_MIN` environment variable – or setting it to empty string – will disable the cron daemon.
 Not passing the `CRON_MIN` environment variable – or setting it to empty string – will disable the cron daemon.
 
 
 ```sh
 ```sh
-sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
-  -v $(pwd)/data:/var/www/FreshRSS/data \
+sudo docker run ... \
   -e 'CRON_MIN=13,43' \
   -e 'CRON_MIN=13,43' \
-  -p 8080:80 \
   --name freshrss freshrss/freshrss
   --name freshrss freshrss/freshrss
 ```
 ```
 
 
@@ -129,32 +195,15 @@ See cron option 1 for customising the cron schedule.
 
 
 ```sh
 ```sh
 sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
 sudo docker run -d --restart unless-stopped --log-opt max-size=10m \
-  -v $(pwd)/data:/var/www/FreshRSS/data \
+  -v freshrss-data:/var/www/FreshRSS/data \
   -e 'CRON_MIN=17,37' \
   -e 'CRON_MIN=17,37' \
+  --net freshrss-network \
   --name freshrss_cron freshrss/freshrss \
   --name freshrss_cron freshrss/freshrss \
   crond -f -d 6
   crond -f -d 6
 ```
 ```
 
 
 
 
-## Debugging
-
-```sh
-# See FreshRSS data (it is on the host)
-cd ./data/
-# See Web server logs
-sudo docker logs -f freshrss
-
-# Enter inside FreshRSS docker container
-sudo docker exec -it freshrss sh
-## See FreshRSS root inside the container
-ls /var/www/FreshRSS/
-```
-
-## Deployment in production
-
-Use a reverse proxy on your host server, such as [Træfik](https://traefik.io/)
-or [nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/),
-with HTTPS, for instance using [Let’s Encrypt](https://letsencrypt.org/).
+## More deployment options
 
 
 ### Example with [docker-compose](https://docs.docker.com/compose/)
 ### Example with [docker-compose](https://docs.docker.com/compose/)
 
 
@@ -167,7 +216,56 @@ A [docker-compose.yml](docker-compose.yml) file is given as an example, using Po
 	* options under the `labels` section are specific to [Træfik](https://traefik.io/), a reverse proxy. If you are not using it, feel free to delete this section. If you are using it, adapt accordingly to your config, especially the `traefik.frontend.rule` option.
 	* options under the `labels` section are specific to [Træfik](https://traefik.io/), a reverse proxy. If you are not using it, feel free to delete this section. If you are using it, adapt accordingly to your config, especially the `traefik.frontend.rule` option.
 	* the `environment` section to adapt the strategy to update feeds.
 	* the `environment` section to adapt the strategy to update feeds.
 
 
-You can then launch the stack (postgres + freshrss) with:
+You can then launch the stack (FreshRSS + PostgreSQL) with:
 ```sh
 ```sh
-docker-compose up -d
+sudo docker-compose up -d
+```
+
+### Alternative reverse proxy using [nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/)
+
+Here is an example of configuration to run FreshRSS behind an Nginx reverse proxy (as subdirectory).
+In particular, the proxy should be setup to allow cookies via HTTP headers (see `proxy_cookie_path` below) to allow logging in via the Web form method.
+
+```
+upstream freshrss {
+	server 127.0.0.1:8080;
+	keepalive 64;
+}
+
+server {
+	listen 80;
+
+	location / {
+		return 301 https://$host$request_uri;
+	}
+}
+
+server {
+	server_name mywebsite.example.net;
+	listen 443 ssl http2;
+
+	# Other SSL stuff goes here
+
+	# Needed for Freshrss cookie/session :
+	proxy_cookie_path / "/; HTTPOnly; Secure";
+
+	location / {
+		try_files $uri $uri/ =404;
+		index index.htm index.html;
+	}
+
+	location /freshrss/ {
+		proxy_pass http://freshrss/;
+		add_header X-Frame-Options SAMEORIGIN;
+		add_header X-XSS-Protection "1; mode=block";
+		proxy_redirect off;
+		proxy_buffering off;
+		proxy_set_header Host $host;
+		proxy_set_header X-Real-IP $remote_addr;
+		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+		proxy_set_header X-Forwarded-Proto $scheme;
+		proxy_set_header X-Forwarded-Port $server_port;
+		proxy_read_timeout 90;
+	}
+}
 ```
 ```

+ 47 - 31
LICENSE.txt

@@ -1,4 +1,5 @@
-[![Build Status][travis-badge]][travis-link]
+[![Statut de la compilation](https://travis-ci.org/FreshRSS/FreshRSS.svg)](https://travis-ci.org/FreshRSS/FreshRSS)
+[![Dons Liberapay](https://img.shields.io/liberapay/receives/FreshRSS.svg?logo=liberapay)](https://liberapay.com/FreshRSS/donate)
 
 
 * Lire ce document sur [github.com/FreshRSS/FreshRSS/](https://github.com/FreshRSS/FreshRSS/blob/master/README.md) pour avoir les images et liens corrects.
 * Lire ce document sur [github.com/FreshRSS/FreshRSS/](https://github.com/FreshRSS/FreshRSS/blob/master/README.md) pour avoir les images et liens corrects.
 * [English version](README.md)
 * [English version](README.md)
@@ -8,46 +9,62 @@ FreshRSS est un agrégateur de flux RSS à auto-héberger à l’image de [Leed]
 
 
 Il se veut léger et facile à prendre en main tout en étant un outil puissant et paramétrable.
 Il se veut léger et facile à prendre en main tout en étant un outil puissant et paramétrable.
 
 
-Il permet de gérer plusieurs utilisateurs, et dispose d’un mode de lecture anonyme.
-Il supporte les étiquettes personnalisées, et [PubSubHubbub](https://github.com/pubsubhubbub/PubSubHubbub) pour des notifications instantanées depuis les sites compatibles.
+Il permet de gérer plusieurs utilisateurs, dispose d’un mode de lecture anonyme, et supporte les étiquettes personnalisées.
 Il y a une API pour les clients (mobiles), ainsi qu’une [interface en ligne de commande](cli/README.md).
 Il y a une API pour les clients (mobiles), ainsi qu’une [interface en ligne de commande](cli/README.md).
+
+Grâce au standard [WebSub](https://www.w3.org/TR/websub/) (anciennement [PubSubHubbub](https://github.com/pubsubhubbub/PubSubHubbub)),
+FreshRSS est capable de recevoir des notifications push instantanées depuis les sources compatibles, telles [Mastodon](https://joinmastodon.org), [Friendica](https://friendi.ca), [WordPress](https://wordpress.org/plugins/pubsubhubbub/), Blogger, FeedBurner, etc.
+
 Enfin, il permet l’ajout d’[extensions](#extensions) pour encore plus de personnalisation.
 Enfin, il permet l’ajout d’[extensions](#extensions) pour encore plus de personnalisation.
 
 
+Les demandes de fonctionnalités, rapports de bugs, et autres contributions sont les bienvenues. Privilégiez pour cela des [demandes sur GitHub](https://github.com/FreshRSS/FreshRSS/issues).
+Nous sommes une communauté amicale.
+
 * Site officiel : https://freshrss.org
 * Site officiel : https://freshrss.org
 * Démo : http://demo.freshrss.org/
 * Démo : http://demo.freshrss.org/
 * Licence : [GNU AGPL 3](https://www.gnu.org/licenses/agpl-3.0.fr.html)
 * Licence : [GNU AGPL 3](https://www.gnu.org/licenses/agpl-3.0.fr.html)
 
 
 ![Logo de FreshRSS](docs/img/FreshRSS-logo.png)
 ![Logo de FreshRSS](docs/img/FreshRSS-logo.png)
 
 
-# Téléchargement
-Voir la [liste des versions](../../releases).
+# Avertissements
+FreshRSS n’est fourni avec aucune garantie.
 
 
-## À propos des branches
-* Utilisez [la branche master](https://github.com/FreshRSS/FreshRSS/tree/master/) si vous visez la stabilité.
-* Pour ceux qui veulent bien aider à tester ou déveloper les dernières fonctionnalités, [la branche dev](https://github.com/FreshRSS/FreshRSS/tree/dev) vous ouvre les bras !
+![Capture d’écran de FreshRSS](docs/img/FreshRSS-screenshot.png)
 
 
-# Avertissements
-Cette application a été développée pour s’adapter principalement à des besoins personnels, et aucune garantie n’est fournie.
-Les demandes de fonctionnalités, rapports de bugs, et autres contributions sont les bienvenues. Privilégiez pour cela des [demandes sur GitHub](https://github.com/FreshRSS/FreshRSS/issues).
-Nous sommes une communauté amicale.
+# [Documentation](https://freshrss.github.io/FreshRSS/fr/)
+* La [documentation utilisateurs](https://freshrss.github.io/FreshRSS/fr/users/02_First_steps.md) pour découvrir les fonctionnalités de FreshRSS.
+* La [documentation administrateurs](https://freshrss.github.io/FreshRSS/fr/users/01_Installation.md) pour l’installation et la maintenance de FreshRSS.
+* La [documentation développeurs](https://freshrss.github.io/FreshRSS/fr/developers/01_First_steps.md) pour savoir comment contribuer et mieux comprendre le code source de FreshRSS.
+* Le [guide de contribution](https://freshrss.github.io/FreshRSS/fr/contributing.md) pour nous aider à développer FreshRSS.
 
 
 # Prérequis
 # Prérequis
+* Un navigateur Web récent tel que Firefox / IceCat, Internet Explorer 11 / Edge (sauf certains détails), Chromium / Chrome, Opera, Safari.
+	* Fonctionne aussi sur mobile (sauf certaines fonctionnalités)
 * Serveur modeste, par exemple sous Linux ou Windows
 * Serveur modeste, par exemple sous Linux ou Windows
 	* Fonctionne même sur un Raspberry Pi 1 avec des temps de réponse < 1s (testé sur 150 flux, 22k articles)
 	* Fonctionne même sur un Raspberry Pi 1 avec des temps de réponse < 1s (testé sur 150 flux, 22k articles)
 * Serveur Web Apache2 (recommandé), ou nginx, lighttpd (non testé sur les autres)
 * Serveur Web Apache2 (recommandé), ou nginx, lighttpd (non testé sur les autres)
-* PHP 5.3.8+ (PHP 5.4+ recommandé, et PHP 5.5+ pour les performances, et PHP 7+ pour d’encore meilleures performances)
+* PHP 5.3.8+ (PHP 5.4+ recommandé, et PHP 5.5+ pour les performances, ou PHP 7+ pour d’encore meilleures performances)
 	* Requis : [cURL](https://secure.php.net/curl), [DOM](https://secure.php.net/dom), [XML](https://secure.php.net/xml), [session](https://secure.php.net/session), [ctype](https://secure.php.net/ctype), et [PDO_MySQL](https://secure.php.net/pdo-mysql) ou [PDO_SQLite](https://secure.php.net/pdo-sqlite) ou [PDO_PGSQL](https://secure.php.net/pdo-pgsql)
 	* Requis : [cURL](https://secure.php.net/curl), [DOM](https://secure.php.net/dom), [XML](https://secure.php.net/xml), [session](https://secure.php.net/session), [ctype](https://secure.php.net/ctype), et [PDO_MySQL](https://secure.php.net/pdo-mysql) ou [PDO_SQLite](https://secure.php.net/pdo-sqlite) ou [PDO_PGSQL](https://secure.php.net/pdo-pgsql)
 	* Recommandés : [JSON](https://secure.php.net/json), [GMP](https://secure.php.net/gmp) (pour accès API sur plateformes < 64 bits), [IDN](https://secure.php.net/intl.idn) (pour les noms de domaines internationalisés), [mbstring](https://secure.php.net/mbstring) (pour le texte Unicode), [iconv](https://secure.php.net/iconv) (pour conversion d’encodages), [ZIP](https://secure.php.net/zip) (pour import/export), [zlib](https://secure.php.net/zlib) (pour les flux compressés)
 	* Recommandés : [JSON](https://secure.php.net/json), [GMP](https://secure.php.net/gmp) (pour accès API sur plateformes < 64 bits), [IDN](https://secure.php.net/intl.idn) (pour les noms de domaines internationalisés), [mbstring](https://secure.php.net/mbstring) (pour le texte Unicode), [iconv](https://secure.php.net/iconv) (pour conversion d’encodages), [ZIP](https://secure.php.net/zip) (pour import/export), [zlib](https://secure.php.net/zlib) (pour les flux compressés)
 * MySQL 5.5.3+ (recommandé), ou SQLite 3.7.4+, ou PostgreSQL 9.2+
 * MySQL 5.5.3+ (recommandé), ou SQLite 3.7.4+, ou PostgreSQL 9.2+
-* Un navigateur Web récent tel que Firefox / IceCat, Internet Explorer 11 / Edge, Chromium / Chrome, Opera, Safari.
-	* Fonctionne aussi sur mobile
 
 
-![Capture d’écran de FreshRSS](docs/img/FreshRSS-screenshot.png)
 
 
-# Documentation
-* https://freshrss.github.io/FreshRSS/fr/
+# Téléchargement
+Voir la [liste des versions](../../releases).
+
+## À propos des branches
+* Utilisez [la branche master](https://github.com/FreshRSS/FreshRSS/tree/master/) si vous souhaitez des versions moins fréquentes et stables.
+* Utilisez [la branche dev](https://github.com/FreshRSS/FreshRSS/tree/dev) si vous vouler une publication continue (rolling release) avec les dernières nouveautés, ou bien aider à tester ou développer la future version stable.
+
 
 
 # [Installation](https://freshrss.github.io/FreshRSS/fr/users/01_Installation.html)
 # [Installation](https://freshrss.github.io/FreshRSS/fr/users/01_Installation.html)
+
+## Installation automatisée
+* [![Docker](https://www.docker.com/sites/default/files/horizontal.png)](./Docker/)
+* [![YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=freshrss)
+* [![Cloudron](https://cloudron.io/img/button.svg)](https://cloudron.io/button.html?app=org.freshrss.cloudronapp)
+
+## Installation manuelle
 1. Récupérez l’application FreshRSS via la commande git ou [en téléchargeant l’archive](../releases)
 1. Récupérez l’application FreshRSS via la commande git ou [en téléchargeant l’archive](../releases)
 2. Placez l’application sur votre serveur (la partie à exposer au Web est le répertoire `./p/`)
 2. Placez l’application sur votre serveur (la partie à exposer au Web est le répertoire `./p/`)
 3. Le serveur Web doit avoir les droits d’écriture dans le répertoire `./data/`
 3. Le serveur Web doit avoir les droits d’écriture dans le répertoire `./data/`
@@ -59,12 +76,7 @@ Nous sommes une communauté amicale.
 
 
 Plus d’informations sur l’installation et la configuration serveur peuvent être trouvées dans [notre documentation](https://freshrss.github.io/FreshRSS/fr/users/01_Installation.md).
 Plus d’informations sur l’installation et la configuration serveur peuvent être trouvées dans [notre documentation](https://freshrss.github.io/FreshRSS/fr/users/01_Installation.md).
 
 
-## Installation automatisée
-* [![Docker](https://www.docker.com/sites/default/files/horizontal.png)](./Docker/)
-* [![YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=freshrss)
-* [![Cloudron](https://cloudron.io/img/button.svg)](https://cloudron.io/button.html?app=org.freshrss.cloudronapp)
-
-## Exemple d’installation complète sur Linux Debian/Ubuntu
+### Exemple d’installation complète sur Linux Debian/Ubuntu
 ```sh
 ```sh
 # Si vous utilisez le serveur Web Apache (sinon il faut un autre serveur Web)
 # Si vous utilisez le serveur Web Apache (sinon il faut un autre serveur Web)
 sudo apt-get install apache2
 sudo apt-get install apache2
@@ -131,8 +143,7 @@ Créer `/etc/cron.d/FreshRSS` avec :
 7,37 * * * * www-data php -f /usr/share/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log 2>&1
 7,37 * * * * www-data php -f /usr/share/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log 2>&1
 ```
 ```
 
 
-
-# Conseils
+## Conseils
 * Pour une meilleure sécurité, faites en sorte que seul le répertoire `./p/` soit accessible depuis le Web, par exemple en faisant pointer un sous-domaine sur le répertoire `./p/`.
 * Pour une meilleure sécurité, faites en sorte que seul le répertoire `./p/` soit accessible depuis le Web, par exemple en faisant pointer un sous-domaine sur le répertoire `./p/`.
 	* En particulier, les données personnelles se trouvent dans le répertoire `./data/`.
 	* En particulier, les données personnelles se trouvent dans le répertoire `./data/`.
 * Le fichier `./constants.php` définit les chemins d’accès aux répertoires clés de l’application. Si vous les bougez, tout se passe ici.
 * Le fichier `./constants.php` définit les chemins d’accès aux répertoires clés de l’application. Si vous les bougez, tout se passe ici.
@@ -140,6 +151,11 @@ Créer `/etc/cron.d/FreshRSS` avec :
 	* Le répertoire spécial `./data/users/_/` contient la partie des logs partagés par tous les utilisateurs.
 	* Le répertoire spécial `./data/users/_/` contient la partie des logs partagés par tous les utilisateurs.
 
 
 
 
+# F.A.Q. :
+* La date et l’heure dans la colonne de droite sont celles déclarées par le flux, pas l’heure à laquelle les articles ont été reçus par FreshRSS, et cette colonne n’est pas utilisée pour le tri.
+	* En particulier, lors de l’import d’un nouveau flux, ses articles sont importés en tête de liste.
+
+
 # Sauvegarde
 # Sauvegarde
 * Il faut conserver vos fichiers `./data/config.php` ainsi que `./data/users/*/config.php`
 * Il faut conserver vos fichiers `./data/config.php` ainsi que `./data/users/*/config.php`
 * Vous pouvez exporter votre liste de flux au format OPML soit depuis l’interface Web, soit [en ligne de commande](cli/README.md)
 * Vous pouvez exporter votre liste de flux au format OPML soit depuis l’interface Web, soit [en ligne de commande](cli/README.md)
@@ -157,7 +173,7 @@ Voir le [dépôt dédié à ces extensions](https://github.com/FreshRSS/Extensio
 
 
 # APIs et applications natives
 # APIs et applications natives
 
 
-FreshRSS supporte l’accès depuis des applications native pour Linux, Android, iOS, et OS X, grâce à deux APIs distinctes.
+FreshRSS supporte l’accès depuis des applications natives pour Linux, Android, iOS, et OS X, grâce à deux APIs distinctes.
 
 
 ## Via l’API compatible Google Reader
 ## Via l’API compatible Google Reader
 
 
@@ -171,6 +187,8 @@ Tout client supportant une API de type Google Reader ; Sélection :
 	* [EasyRSS](https://github.com/Alkarex/EasyRSS) (Libre, [F-Droid](https://f-droid.org/fr/packages/org.freshrss.easyrss/))
 	* [EasyRSS](https://github.com/Alkarex/EasyRSS) (Libre, [F-Droid](https://f-droid.org/fr/packages/org.freshrss.easyrss/))
 * GNU/Linux
 * GNU/Linux
 	* [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Libre)
 	* [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Libre)
+* MacOS
+	* [Vienna RSS](http://www.vienna-rss.com/) (Libre)
 
 
 ## Via l’API compatible Fever
 ## Via l’API compatible Fever
 
 
@@ -192,16 +210,14 @@ Tout client supportant une API de type Fever ; Sélection :
 * [php-http-304](https://alexandre.alapetite.fr/doc-alex/php-http-304/)
 * [php-http-304](https://alexandre.alapetite.fr/doc-alex/php-http-304/)
 * [jQuery](https://jquery.com/)
 * [jQuery](https://jquery.com/)
 * [lib_opml](https://github.com/marienfressinaud/lib_opml)
 * [lib_opml](https://github.com/marienfressinaud/lib_opml)
-* [jQuery Plugin Sticky-Kit](https://leafo.net/sticky-kit/)
 * [keyboard_shortcuts](http://www.openjs.com/scripts/events/keyboard_shortcuts/)
 * [keyboard_shortcuts](http://www.openjs.com/scripts/events/keyboard_shortcuts/)
 * [flotr2](http://www.humblesoftware.com/flotr2)
 * [flotr2](http://www.humblesoftware.com/flotr2)
 
 
-## Uniquement pour certaines options
+## Uniquement pour certaines options ou configurations
 * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js)
 * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js)
 * [phpQuery](https://github.com/phpquery/phpquery)
 * [phpQuery](https://github.com/phpquery/phpquery)
-
-## Si les fonctions natives ne sont pas disponibles
 * [Services_JSON](https://pear.php.net/pepr/pepr-proposal-show.php?id=198)
 * [Services_JSON](https://pear.php.net/pepr/pepr-proposal-show.php?id=198)
 * [password_compat](https://github.com/ircmaxell/password_compat)
 * [password_compat](https://github.com/ircmaxell/password_compat)
 
 
 
 
+

+ 58 - 43
README.md

@@ -1,70 +1,82 @@
 [![Build Status][travis-badge]][travis-link]
 [![Build Status][travis-badge]][travis-link]
+[![Liberapay donations](https://img.shields.io/liberapay/receives/FreshRSS.svg?logo=liberapay)](https://liberapay.com/FreshRSS/donate)
 
 
 * Read this document on [github.com/FreshRSS/FreshRSS/](https://github.com/FreshRSS/FreshRSS/blob/master/README.md) to get the correct links and pictures.
 * Read this document on [github.com/FreshRSS/FreshRSS/](https://github.com/FreshRSS/FreshRSS/blob/master/README.md) to get the correct links and pictures.
 * [Version française](README.fr.md)
 * [Version française](README.fr.md)
 
 
 # FreshRSS
 # FreshRSS
-FreshRSS is a self-hosted RSS feed aggregator such as [Leed](http://leed.idleman.fr/) or [Kriss Feed](https://tontof.net/kriss/feed/).
+FreshRSS is a self-hosted RSS feed aggregator like [Leed](http://leed.idleman.fr/) or [Kriss Feed](https://tontof.net/kriss/feed/).
 
 
-It is at the same time lightweight, easy to work with, powerful and customizable.
+It is lightweight, easy to work with, powerful, and customizable.
 
 
-It is a multi-user application with an anonymous reading mode.
-It supports custom tags, and [PubSubHubbub](https://github.com/pubsubhubbub/PubSubHubbub) for instant notifications from compatible Web sites.
+It is a multi-user application with an anonymous reading mode. It supports custom tags.
 There is an API for (mobile) clients, and a [Command-Line Interface](cli/README.md).
 There is an API for (mobile) clients, and a [Command-Line Interface](cli/README.md).
+
+Thanks to the [WebSub](https://www.w3.org/TR/websub/) standard (formerly [PubSubHubbub](https://github.com/pubsubhubbub/PubSubHubbub)),
+FreshRSS is able to receive instant push notifications from compatible sources, such as [Mastodon](https://joinmastodon.org), [Friendica](https://friendi.ca), [WordPress](https://wordpress.org/plugins/pubsubhubbub/), Blogger, FeedBurner, etc.
+
 Finally, it supports [extensions](#extensions) for further tuning.
 Finally, it supports [extensions](#extensions) for further tuning.
 
 
+Feature requests, bug reports, and other contributions are welcome. The best way to contribute is to [open an issue on GitHub](https://github.com/FreshRSS/FreshRSS/issues).
+We are a friendly community.
+
 * Official website: https://freshrss.org
 * Official website: https://freshrss.org
 * Demo: https://demo.freshrss.org/
 * Demo: https://demo.freshrss.org/
 * License: [GNU AGPL 3](https://www.gnu.org/licenses/agpl-3.0.html)
 * License: [GNU AGPL 3](https://www.gnu.org/licenses/agpl-3.0.html)
 
 
 ![FreshRSS logo](docs/img/FreshRSS-logo.png)
 ![FreshRSS logo](docs/img/FreshRSS-logo.png)
 
 
-# Releases
-See the [list of releases](../../releases).
+# Disclaimer
+FreshRSS comes with absolutely no warranty.
 
 
-## About branches
-* Use [the master branch](https://github.com/FreshRSS/FreshRSS/tree/master/) if you need a stable version.
-* For those willing to help testing or developing the latest features, [the dev branch](https://github.com/FreshRSS/FreshRSS/tree/dev) is waiting for you!
+![FreshRSS screenshot](docs/img/FreshRSS-screenshot.png)
 
 
-# Disclaimer
-This application was developed to fulfil personal needs primarily, and comes with absolutely no warranty.
-Feature requests, bug reports, and other contributions are welcome. The best way is to [open an issue on GitHub](https://github.com/FreshRSS/FreshRSS/issues).
-We are a friendly community.
+# [Documentation](https://freshrss.github.io/FreshRSS/en/)
+* [User documentation](https://freshrss.github.io/FreshRSS/en/users/02_First_steps.html), where you can discover all the possibilities offered by FreshRSS
+* [Administrator documentation](https://freshrss.github.io/FreshRSS/en/admins/01_Index.html) for detailed installation and maintenance related tasks
+* [Developer documentation](https://freshrss.github.io/FreshRSS/en/developers/01_First_steps.html) to guide you in the source code of FreshRSS and to help you if you want to contribute
+* [Contributor guidelines](https://freshrss.github.io/FreshRSS/en/contributing.md) for those who want to help improve FreshRSS
 
 
 # Requirements
 # Requirements
+* A recent browser like Firefox / IceCat, Internet Explorer 11 / Edge (minus a few details), Chromium / Chrome, Opera, Safari.
+	* Works on mobile (except a few features)
 * Light server running Linux or Windows
 * Light server running Linux or Windows
 	* It even works on Raspberry Pi 1 with response time under a second (tested with 150 feeds, 22k articles)
 	* It even works on Raspberry Pi 1 with response time under a second (tested with 150 feeds, 22k articles)
 * A web server: Apache2 (recommended), nginx, lighttpd (not tested on others)
 * A web server: Apache2 (recommended), nginx, lighttpd (not tested on others)
-* PHP 5.3.8+ (PHP 5.4+ recommended, and PHP 5.5+ for performance, and PHP 7 for even higher performance)
+* PHP 5.3.8+ (PHP 5.4+ recommended, and PHP 5.5+ for performance, or PHP 7 for even higher performance)
 	* Required extensions: [cURL](https://secure.php.net/curl), [DOM](https://secure.php.net/dom), [XML](https://secure.php.net/xml), [session](https://secure.php.net/session), [ctype](https://secure.php.net/ctype), and [PDO_MySQL](https://secure.php.net/pdo-mysql) or [PDO_SQLite](https://secure.php.net/pdo-sqlite) or [PDO_PGSQL](https://secure.php.net/pdo-pgsql)
 	* Required extensions: [cURL](https://secure.php.net/curl), [DOM](https://secure.php.net/dom), [XML](https://secure.php.net/xml), [session](https://secure.php.net/session), [ctype](https://secure.php.net/ctype), and [PDO_MySQL](https://secure.php.net/pdo-mysql) or [PDO_SQLite](https://secure.php.net/pdo-sqlite) or [PDO_PGSQL](https://secure.php.net/pdo-pgsql)
-	* Recommended extensions: [JSON](https://secure.php.net/json), [GMP](https://secure.php.net/gmp) (for API access on platforms < 64 bits), [IDN](https://secure.php.net/intl.idn) (for Internationalized Domain Names), [mbstring](https://secure.php.net/mbstring) (for Unicode strings), [iconv](https://secure.php.net/iconv) (for charset conversion), [ZIP](https://secure.php.net/zip) (for import/export), [zlib](https://secure.php.net/zlib) (for compressed feeds)
+	* Recommended extensions: [JSON](https://secure.php.net/json), [GMP](https://secure.php.net/gmp) (for API access on 32-bit platforms), [IDN](https://secure.php.net/intl.idn) (for Internationalized Domain Names), [mbstring](https://secure.php.net/mbstring) (for Unicode strings), [iconv](https://secure.php.net/iconv) (for charset conversion), [ZIP](https://secure.php.net/zip) (for import/export), [zlib](https://secure.php.net/zlib) (for compressed feeds)
 * MySQL 5.5.3+ (recommended), or SQLite 3.7.4+, or PostgreSQL 9.2+
 * MySQL 5.5.3+ (recommended), or SQLite 3.7.4+, or PostgreSQL 9.2+
-* A recent browser like Firefox / IceCat, Internet Explorer 11 / Edge, Chromium / Chrome, Opera, Safari.
-	* Works on mobile
 
 
-![FreshRSS screenshot](docs/img/FreshRSS-screenshot.png)
 
 
-# Documentation
-* https://freshrss.github.io/FreshRSS/en/
+# Releases
+See the [list of releases](../../releases).
+
+## About branches
+* Use [the master branch](https://github.com/FreshRSS/FreshRSS/tree/master/) if you need less frequent stable versions.
+* Use [the dev branch](https://github.com/FreshRSS/FreshRSS/tree/dev) if you want a rolling release with the newest features, or help testing or developing the next stable version.
+
 
 
 # [Installation](https://freshrss.github.io/FreshRSS/en/admins/02_Installation.html)
 # [Installation](https://freshrss.github.io/FreshRSS/en/admins/02_Installation.html)
+
+## Automated install
+* [![Docker](https://www.docker.com/sites/default/files/horizontal.png)](./Docker/)
+* [![YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=freshrss)
+* [![Cloudron](https://cloudron.io/img/button.svg)](https://cloudron.io/button.html?app=org.freshrss.cloudronapp)
+
+## Manual install
 1. Get FreshRSS with git or [by downloading the archive](https://github.com/FreshRSS/FreshRSS/archive/master.zip)
 1. Get FreshRSS with git or [by downloading the archive](https://github.com/FreshRSS/FreshRSS/archive/master.zip)
-2. Dump the application on your server (expose only the `./p/` folder)
-3. Add write access on `./data/` folder to the webserver user
+2. Put the application somewhere on your server (expose only the `./p/` folder to the Web)
+3. Add write access to the `./data/` folder for the webserver user
 4. Access FreshRSS with your browser and follow the installation process
 4. Access FreshRSS with your browser and follow the installation process
 	* or use the [Command-Line Interface](cli/README.md)
 	* or use the [Command-Line Interface](cli/README.md)
-5. Everything should be working :) If you encounter any problem, feel free [contact us](https://github.com/FreshRSS/FreshRSS/issues).
-6. Advanced configuration settings can be seen in [config.default.php](config.default.php) and modified in `data/config.php`.
+5. Everything should be working :) If you encounter any problems, feel free to [contact us](https://github.com/FreshRSS/FreshRSS/issues).
+6. Advanced configuration settings can be found in [config.default.php](config.default.php) and modified in `data/config.php`.
 7. When using Apache, enable [`AllowEncodedSlashes`](https://httpd.apache.org/docs/trunk/mod/core.html#allowencodedslashes) for better compatibility with mobile clients.
 7. When using Apache, enable [`AllowEncodedSlashes`](https://httpd.apache.org/docs/trunk/mod/core.html#allowencodedslashes) for better compatibility with mobile clients.
 
 
-More information about installation and server configuration can be found in [our documentation](https://freshrss.github.io/FreshRSS/en/admins/02_Installation.html).
+More detailed information about installation and server configuration can be found in [our documentation](https://freshrss.github.io/FreshRSS/en/admins/02_Installation.html).
 
 
-## Automated install 
-* [![Docker](https://www.docker.com/sites/default/files/horizontal.png)](./Docker/)
-* [![YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=freshrss)
-* [![Cloudron](https://cloudron.io/img/button.svg)](https://cloudron.io/button.html?app=org.freshrss.cloudronapp)
-
-## Example of full installation on Linux Debian/Ubuntu
+### Example of full installation on Linux Debian/Ubuntu
 ```sh
 ```sh
 # If you use an Apache Web server (otherwise you need another Web server)
 # If you use an Apache Web server (otherwise you need another Web server)
 sudo apt-get install apache2
 sudo apt-get install apache2
@@ -108,16 +120,16 @@ 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).
 See more commands and git commands in the [Command-Line Interface documentation](cli/README.md).
 
 
 ## Access control
 ## Access control
-It is needed for the multi-user mode to limit access to FreshRSS. You can:
-* use form authentication (needs JavaScript, and PHP 5.5+ recommended)
-* use HTTP authentication supported by your web server
+This is needed if you will be using the multi-user mode, to limit access to FreshRSS. Options Available:
+* form authentication (needs JavaScript, and PHP 5.5+ recommended)
+* HTTP authentication supported by your web server
 	* See [Apache documentation](https://httpd.apache.org/docs/trunk/howto/auth.html)
 	* See [Apache documentation](https://httpd.apache.org/docs/trunk/howto/auth.html)
 		* In that case, create a `./p/i/.htaccess` file with a matching `.htpasswd` file.
 		* In that case, create a `./p/i/.htaccess` file with a matching `.htpasswd` file.
 
 
 ## Automatic feed update
 ## Automatic feed update
 * You can add a Cron job to launch the update script.
 * You can add a Cron job to launch the update script.
 Check the Cron documentation related to your distribution ([Debian/Ubuntu](https://help.ubuntu.com/community/CronHowto), [Red Hat/Fedora](https://fedoraproject.org/wiki/Administration_Guide_Draft/Cron), [Slackware](https://docs.slackware.com/fr:slackbook:process_control?#cron), [Gentoo](https://wiki.gentoo.org/wiki/Cron), [Arch Linux](https://wiki.archlinux.org/index.php/Cron)…).
 Check the Cron documentation related to your distribution ([Debian/Ubuntu](https://help.ubuntu.com/community/CronHowto), [Red Hat/Fedora](https://fedoraproject.org/wiki/Administration_Guide_Draft/Cron), [Slackware](https://docs.slackware.com/fr:slackbook:process_control?#cron), [Gentoo](https://wiki.gentoo.org/wiki/Cron), [Arch Linux](https://wiki.archlinux.org/index.php/Cron)…).
-It is a good idea to use the Web server user.
+It is a good idea to run the cron job as the webserver user (often “www-data”).
 For instance, if you want to run the script every hour:
 For instance, if you want to run the script every hour:
 
 
 ```
 ```
@@ -131,15 +143,19 @@ Create `/etc/cron.d/FreshRSS` with:
 6,36 * * * * www-data php -f /usr/share/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log 2>&1
 6,36 * * * * www-data php -f /usr/share/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log 2>&1
 ```
 ```
 
 
-
-# Advices
-* For a better security, expose only the `./p/` folder on the Web.
+## Advice
+* For better security, expose only the `./p/` folder to the Web.
 	* Be aware that the `./data/` folder contains all personal data, so it is a bad idea to expose it.
 	* Be aware that the `./data/` folder contains all personal data, so it is a bad idea to expose it.
-* The `./constants.php` file defines access to application folder. If you want to customize your installation, every thing happens here.
+* The `./constants.php` file defines access to the application folder. If you want to customize your installation, look here first.
 * If you encounter any problem, logs are accessible from the interface or manually in `./data/users/*/log*.txt` files.
 * If you encounter any problem, logs are accessible from the interface or manually in `./data/users/*/log*.txt` files.
 	* The special folder `./data/users/_/` contains the part of the logs that are shared by all users.
 	* The special folder `./data/users/_/` contains the part of the logs that are shared by all users.
 
 
 
 
+# F.A.Q.:
+* The date and time in the right-hand column is the date declared by the feed, not the time at which the article was received by FreshRSS, and it is not used for sorting.
+	* In particular, when importing a new feed, all of its articles will appear at the top of the feed list regardless of their declared date.
+
+
 # Backup
 # Backup
 * You need to keep `./data/config.php`, and `./data/users/*/config.php` files
 * You need to keep `./data/config.php`, and `./data/users/*/config.php` files
 * You can export your feed list in OPML format either from the Web interface, or from the [Command-Line Interface](cli/README.md)
 * You can export your feed list in OPML format either from the Web interface, or from the [Command-Line Interface](cli/README.md)
@@ -171,6 +187,8 @@ Supported clients are:
 	* [EasyRSS](https://github.com/Alkarex/EasyRSS) (Open source, [F-Droid](https://f-droid.org/packages/org.freshrss.easyrss/))
 	* [EasyRSS](https://github.com/Alkarex/EasyRSS) (Open source, [F-Droid](https://f-droid.org/packages/org.freshrss.easyrss/))
 * GNU/Linux
 * GNU/Linux
 	* [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Open source)
 	* [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Open source)
+* MacOS
+	* [Vienna RSS](http://www.vienna-rss.com/) (Open source)
 
 
 ## Fever API
 ## Fever API
 
 
@@ -192,15 +210,12 @@ Supported clients are:
 * [php-http-304](https://alexandre.alapetite.fr/doc-alex/php-http-304/)
 * [php-http-304](https://alexandre.alapetite.fr/doc-alex/php-http-304/)
 * [jQuery](https://jquery.com/)
 * [jQuery](https://jquery.com/)
 * [lib_opml](https://github.com/marienfressinaud/lib_opml)
 * [lib_opml](https://github.com/marienfressinaud/lib_opml)
-* [jQuery Plugin Sticky-Kit](https://leafo.net/sticky-kit/)
 * [keyboard_shortcuts](http://www.openjs.com/scripts/events/keyboard_shortcuts/)
 * [keyboard_shortcuts](http://www.openjs.com/scripts/events/keyboard_shortcuts/)
 * [flotr2](http://www.humblesoftware.com/flotr2)
 * [flotr2](http://www.humblesoftware.com/flotr2)
 
 
-## Only for some options
+## Only for some options or configurations
 * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js)
 * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js)
 * [phpQuery](https://github.com/phpquery/phpquery)
 * [phpQuery](https://github.com/phpquery/phpquery)
-
-## If native functions are not available
 * [Services_JSON](https://pear.php.net/pepr/pepr-proposal-show.php?id=198)
 * [Services_JSON](https://pear.php.net/pepr/pepr-proposal-show.php?id=198)
 * [password_compat](https://github.com/ircmaxell/password_compat)
 * [password_compat](https://github.com/ircmaxell/password_compat)
 
 

+ 2 - 0
app/Controllers/configureController.php

@@ -308,6 +308,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 	 *   - user limit (default: 1)
 	 *   - user limit (default: 1)
 	 *   - user category limit (default: 16384)
 	 *   - user category limit (default: 16384)
 	 *   - user feed limit (default: 16384)
 	 *   - user feed limit (default: 16384)
+	 *   - user login duration for form auth (default: 2592000)
 	 */
 	 */
 	public function systemAction() {
 	public function systemAction() {
 		if (!FreshRSS_Auth::hasAccess('admin')) {
 		if (!FreshRSS_Auth::hasAccess('admin')) {
@@ -318,6 +319,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 			$limits['max_registrations'] = Minz_Request::param('max-registrations', 1);
 			$limits['max_registrations'] = Minz_Request::param('max-registrations', 1);
 			$limits['max_feeds'] = Minz_Request::param('max-feeds', 16384);
 			$limits['max_feeds'] = Minz_Request::param('max-feeds', 16384);
 			$limits['max_categories'] = Minz_Request::param('max-categories', 16384);
 			$limits['max_categories'] = Minz_Request::param('max-categories', 16384);
+			$limits['cookie_duration'] = Minz_Request::param('cookie-duration', 2592000);
 			FreshRSS_Context::$system_conf->limits = $limits;
 			FreshRSS_Context::$system_conf->limits = $limits;
 			FreshRSS_Context::$system_conf->title = Minz_Request::param('instance-name', 'FreshRSS');
 			FreshRSS_Context::$system_conf->title = Minz_Request::param('instance-name', 'FreshRSS');
 			FreshRSS_Context::$system_conf->auto_update_url = Minz_Request::param('auto-update-url', false);
 			FreshRSS_Context::$system_conf->auto_update_url = Minz_Request::param('auto-update-url', false);

+ 6 - 6
app/Controllers/feedController.php

@@ -266,7 +266,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
 		$nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1);
 		$nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1);
 		$date_min = time() - (3600 * 24 * 30 * $nb_month_old);
 		$date_min = time() - (3600 * 24 * 30 * $nb_month_old);
 
 
-		// PubSubHubbub support
+		// WebSub (PubSubHubbub) support
 		$pubsubhubbubEnabledGeneral = FreshRSS_Context::$system_conf->pubsubhubbub_enabled;
 		$pubsubhubbubEnabledGeneral = FreshRSS_Context::$system_conf->pubsubhubbub_enabled;
 		$pshbMinAge = time() - (3600 * 24);  //TODO: Make a configuration.
 		$pshbMinAge = time() - (3600 * 24);  //TODO: Make a configuration.
 
 
@@ -437,13 +437,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
 				$entryDAO->commit();
 				$entryDAO->commit();
 			}
 			}
 
 
-			if ($feed->hubUrl() && $feed->selfUrl()) {	//selfUrl has priority for PubSubHubbub
+			if ($feed->hubUrl() && $feed->selfUrl()) {	//selfUrl has priority for WebSub
 				if ($feed->selfUrl() !== $url) {	//https://code.google.com/p/pubsubhubbub/wiki/MovingFeedsOrChangingHubs
 				if ($feed->selfUrl() !== $url) {	//https://code.google.com/p/pubsubhubbub/wiki/MovingFeedsOrChangingHubs
 					$selfUrl = checkUrl($feed->selfUrl());
 					$selfUrl = checkUrl($feed->selfUrl());
 					if ($selfUrl) {
 					if ($selfUrl) {
-						Minz_Log::debug('PubSubHubbub unsubscribe ' . $feed->url(false));
+						Minz_Log::debug('WebSub unsubscribe ' . $feed->url(false));
 						if (!$feed->pubSubHubbubSubscribe(false)) {	//Unsubscribe
 						if (!$feed->pubSubHubbubSubscribe(false)) {	//Unsubscribe
-							Minz_Log::warning('Error while PubSubHubbub unsubscribing from ' . $feed->url(false));
+							Minz_Log::warning('Error while WebSub unsubscribing from ' . $feed->url(false));
 						}
 						}
 						$feed->_url($selfUrl, false);
 						$feed->_url($selfUrl, false);
 						Minz_Log::notice('Feed ' . $url . ' canonical address moved to ' . $feed->url(false));
 						Minz_Log::notice('Feed ' . $url . ' canonical address moved to ' . $feed->url(false));
@@ -457,9 +457,9 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
 
 
 			$feed->faviconPrepare();
 			$feed->faviconPrepare();
 			if ($pubsubhubbubEnabledGeneral && $feed->pubSubHubbubPrepare()) {
 			if ($pubsubhubbubEnabledGeneral && $feed->pubSubHubbubPrepare()) {
-				Minz_Log::notice('PubSubHubbub subscribe ' . $feed->url(false));
+				Minz_Log::notice('WebSub subscribe ' . $feed->url(false));
 				if (!$feed->pubSubHubbubSubscribe(true)) {	//Subscribe
 				if (!$feed->pubSubHubbubSubscribe(true)) {	//Subscribe
-					Minz_Log::warning('Error while PubSubHubbub subscribing to ' . $feed->url(false));
+					Minz_Log::warning('Error while WebSub subscribing to ' . $feed->url(false));
 				}
 				}
 			}
 			}
 			$feed->unlock();
 			$feed->unlock();

+ 141 - 27
app/Controllers/importExportController.php

@@ -109,6 +109,17 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 				}
 				}
 			}
 			}
 		}
 		}
+		foreach ($list_files['ttrss_starred'] as $article_file) {
+			$json = $this->ttrssXmlToJson($article_file);
+			if (!$this->importJson($json, true)) {
+				$ok = false;
+				if (FreshRSS_Context::$isCli) {
+					fwrite(STDERR, 'FreshRSS error during TT-RSS articles import' . "\n");
+				} else {
+					Minz_Log::warning('Error during TT-RSS articles import');
+				}
+			}
+		}
 
 
 		return $ok;
 		return $ok;
 	}
 	}
@@ -165,17 +176,22 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 	private static function guessFileType($filename) {
 	private static function guessFileType($filename) {
 		if (substr_compare($filename, '.zip', -4) === 0) {
 		if (substr_compare($filename, '.zip', -4) === 0) {
 			return 'zip';
 			return 'zip';
-		} elseif (substr_compare($filename, '.opml', -5) === 0 ||
-		          substr_compare($filename, '.xml', -4) === 0) {
+		} elseif (substr_compare($filename, '.opml', -5) === 0) {
 			return 'opml';
 			return 'opml';
-		} elseif (substr_compare($filename, '.json', -5) === 0 &&
-		          strpos($filename, 'starred') !== false) {
-			return 'json_starred';
 		} elseif (substr_compare($filename, '.json', -5) === 0) {
 		} elseif (substr_compare($filename, '.json', -5) === 0) {
-			return 'json_feed';
-		} else {
-			return 'unknown';
+			if (strpos($filename, 'starred') !== false) {
+				return 'json_starred';
+			} else {
+				return 'json_feed';
+			}
+		} elseif (substr_compare($filename, '.xml', -4) === 0) {
+			if (preg_match('/Tiny|tt-?rss/i', $filename)) {
+				return 'ttrss_starred';
+			} else {
+				return 'opml';
+			}
 		}
 		}
+		return 'unknown';
 	}
 	}
 
 
 	/**
 	/**
@@ -364,6 +380,43 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 		return !$error;
 		return !$error;
 	}
 	}
 
 
+	private function ttrssXmlToJson($xml) {
+		$table = (array)simplexml_load_string($xml, null, LIBXML_NOCDATA);
+		$table['items'] = isset($table['article']) ? $table['article'] : array();
+		unset($table['article']);
+		for ($i = count($table['items']) - 1; $i >= 0; $i--) {
+			$item = (array)($table['items'][$i]);
+			$item['updated'] = isset($item['updated']) ? strtotime($item['updated']) : '';
+			$item['published'] = $item['updated'];
+			$item['content'] = array('content' => isset($item['content']) ? $item['content'] : '');
+			$item['categories'] = isset($item['tag_cache']) ? array($item['tag_cache']) : array();
+			if (!empty($item['marked'])) {
+				$item['categories'][] = 'user/-/state/com.google/starred';
+			}
+			if (!empty($item['published'])) {
+				$item['categories'][] = 'user/-/state/com.google/broadcast';
+			}
+			if (!empty($item['label_cache'])) {
+				$labels_cache = json_decode($item['label_cache'], true);
+				if (is_array($labels_cache)) {
+					foreach ($labels_cache as $label_cache) {
+						if (!empty($label_cache[1])) {
+							$item['categories'][] = 'user/-/label/' . trim($label_cache[1]);
+						}
+					}
+				}
+			}
+			$item['alternate'][0]['href'] = isset($item['link']) ? $item['link'] : '';
+			$item['origin'] = array(
+					'title' => isset($item['feed_title']) ? $item['feed_title'] : '',
+					'feedUrl' => isset($item['feed_url']) ? $item['feed_url'] : '',
+				);
+			$item['id'] = isset($item['guid']) ? $item['guid'] : (isset($item['feed_url']) ? $item['feed_url'] : $item['published']);
+			$table['items'][$i] = $item;
+		}
+		return json_encode($table);
+	}
+
 	/**
 	/**
 	 * This method import a JSON-based file (Google Reader format).
 	 * This method import a JSON-based file (Google Reader format).
 	 *
 	 *
@@ -405,7 +458,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 					// Oops, no more place!
 					// Oops, no more place!
 					Minz_Log::warning(_t('feedback.sub.feed.over_max', $limits['max_feeds']));
 					Minz_Log::warning(_t('feedback.sub.feed.over_max', $limits['max_feeds']));
 				} else {
 				} else {
-					$feed = $this->addFeedJson($item['origin'], $google_compliant);
+					$feed = $this->addFeedJson($item['origin']);
 				}
 				}
 
 
 				if ($feed == null) {
 				if ($feed == null) {
@@ -425,6 +478,15 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 			}
 			}
 		}
 		}
 
 
+		$tagDAO = FreshRSS_Factory::createTagDao();
+		$labels = $tagDAO->listTags();
+		$knownLabels = array();
+		foreach ($labels as $label) {
+			$knownLabels[$label->name()]['id'] = $label->id();
+			$knownLabels[$label->name()]['articles'] = array();
+		}
+		unset($labels);
+
 		// For each feed, check existing GUIDs already in database.
 		// For each feed, check existing GUIDs already in database.
 		$existingHashForGuids = array();
 		$existingHashForGuids = array();
 		foreach ($newFeedGuids as $feedId => $newGuids) {
 		foreach ($newFeedGuids as $feedId => $newGuids) {
@@ -443,19 +505,36 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 
 
 			$feed_id = $article_to_feed[$item['id']];
 			$feed_id = $article_to_feed[$item['id']];
 			$author = isset($item['author']) ? $item['author'] : '';
 			$author = isset($item['author']) ? $item['author'] : '';
-			$key_content = ($google_compliant && !isset($item['content'])) ? 'summary' : 'content';
+			$is_starred = $starred;
 			$tags = $item['categories'];
 			$tags = $item['categories'];
-			if ($google_compliant) {
-				// Remove tags containing "/state/com.google" which are useless.
-				$tags = array_filter($tags, function($var) {
-					return strpos($var, '/state/com.google') !== false;
-				});
+			$labels = array();
+			for ($i = count($tags) - 1; $i >= 0; $i --) {
+				$tag = trim($tags[$i]);
+				if (strpos($tag, 'user/-/') !== false) {
+					if ($tag === 'user/-/state/com.google/starred') {
+						$is_starred = true;
+					} elseif (strpos($tag, 'user/-/label/') === 0) {
+						$tag = trim(substr($tag, 13));
+						if ($tag != '') {
+							$labels[] = $tag;
+						}
+					}
+					unset($tags[$i]);
+				}
+			}
+
+			$url = $item['alternate'][0]['href'];
+			if (!empty($item['content']['content'])) {
+				$content = $item['content']['content'];
+			} elseif (!empty($item['summary']['content'])) {
+				$content = $item['summary']['content'];
 			}
 			}
+			$content = sanitizeHTML($content, $url);
 
 
 			$entry = new FreshRSS_Entry(
 			$entry = new FreshRSS_Entry(
 				$feed_id, $item['id'], $item['title'], $author,
 				$feed_id, $item['id'], $item['title'], $author,
-				$item[$key_content]['content'], $item['alternate'][0]['href'],
-				$item['published'], $is_read, $starred
+				$content, $url,
+				$item['published'], $is_read, $is_starred
 			);
 			);
 			$entry->_id(min(time(), $entry->date(true)) . uSecString());
 			$entry->_id(min(time(), $entry->date(true)) . uSecString());
 			$entry->_tags($tags);
 			$entry->_tags($tags);
@@ -478,8 +557,21 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 			} else {
 			} else {
 				$ok = $this->entryDAO->addEntry($values);
 				$ok = $this->entryDAO->addEntry($values);
 			}
 			}
-			$error |= ($ok === false);
 
 
+			foreach ($labels as $labelName) {
+				if (empty($knownLabels[$labelName]['id'])) {
+					$labelId = $tagDAO->addTag(array('name' => $labelName));
+					$knownLabels[$labelName]['id'] = $labelId;
+					$knownLabels[$labelName]['articles'] = array();
+				}
+				$knownLabels[$labelName]['articles'][] = array(
+						//'id' => $entry->id(),	//ID changes after commitNewEntries()
+						'id_feed' => $entry->feed(),
+						'guid' => $entry->guid(),
+					);
+			}
+
+			$error |= ($ok === false);
 		}
 		}
 		$this->entryDAO->commit();
 		$this->entryDAO->commit();
 
 
@@ -488,6 +580,20 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 		$this->feedDAO->updateCachedValues();
 		$this->feedDAO->updateCachedValues();
 		$this->entryDAO->commit();
 		$this->entryDAO->commit();
 
 
+		$this->entryDAO->beginTransaction();
+		foreach ($knownLabels as $labelName => $knownLabel) {
+			$labelId = $knownLabel['id'];
+			foreach ($knownLabel['articles'] as $article) {
+				$entryId = $this->entryDAO->searchIdByGuid($article['id_feed'], $article['guid']);
+				if ($entryId != null) {
+					$tagDAO->tagEntry($labelId, $entryId);
+				} else {
+					Minz_Log::warning('Could not add label "' . $labelName . '" to entry "' . $article['guid'] . '" in feed ' . $article['id_feed']);
+				}
+			}
+		}
+		$this->entryDAO->commit();
+
 		return !$error;
 		return !$error;
 	}
 	}
 
 
@@ -495,16 +601,24 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 	 * This method import a JSON-based feed (Google Reader format).
 	 * This method import a JSON-based feed (Google Reader format).
 	 *
 	 *
 	 * @param array $origin represents a feed.
 	 * @param array $origin represents a feed.
-	 * @param boolean $google_compliant takes care of some specific values if true.
 	 * @return FreshRSS_Feed if feed is in database at the end of the process,
 	 * @return FreshRSS_Feed if feed is in database at the end of the process,
 	 *         else null.
 	 *         else null.
 	 */
 	 */
-	private function addFeedJson($origin, $google_compliant) {
+	private function addFeedJson($origin) {
 		$return = null;
 		$return = null;
-		$key = $google_compliant ? 'htmlUrl' : 'feedUrl';
-		$url = $origin[$key];
-		$name = $origin['title'];
-		$website = $origin['htmlUrl'];
+		if (!empty($origin['feedUrl'])) {
+			$url = $origin['feedUrl'];
+		} elseif (!empty($origin['htmlUrl'])) {
+			$url = $origin['htmlUrl'];
+		} else {
+			return null;
+		}
+		if (!empty($origin['htmlUrl'])) {
+			$website = $origin['htmlUrl'];
+		} elseif (!empty($origin['feedUrl'])) {
+			$website = $origin['feedUrl'];
+		}
+		$name = empty($origin['title']) ? '' : $origin['title'];
 
 
 		try {
 		try {
 			// Create a Feed object and add it in database.
 			// Create a Feed object and add it in database.
@@ -585,7 +699,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 			// Only one file? Guess its type and export it.
 			// Only one file? Guess its type and export it.
 			$filename = key($export_files);
 			$filename = key($export_files);
 			$type = self::guessFileType($filename);
 			$type = self::guessFileType($filename);
-			$this->sendFile('freshrss_' . $filename, $export_files[$filename], $type);
+			$this->sendFile('freshrss_' . Minz_Session::param('currentUser', '_') . '_' . $filename, $export_files[$filename], $type);
 		}
 		}
 		return $nb_files;
 		return $nb_files;
 	}
 	}
@@ -683,7 +797,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 		}
 		}
 
 
 		// From https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly
 		// From https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly
-		$zip_file = tempnam('tmp', 'zip');
+		$zip_file = @tempnam('/tmp', 'zip');
 		$zip = new ZipArchive();
 		$zip = new ZipArchive();
 		$zip->open($zip_file, ZipArchive::OVERWRITE);
 		$zip->open($zip_file, ZipArchive::OVERWRITE);
 
 
@@ -696,7 +810,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 		header('Content-Type: application/zip');
 		header('Content-Type: application/zip');
 		header('Content-Length: ' . filesize($zip_file));
 		header('Content-Length: ' . filesize($zip_file));
 		$day = date('Y-m-d');
 		$day = date('Y-m-d');
-		header('Content-Disposition: attachment; filename="freshrss_' . $day . '_export.zip"');
+		header('Content-Disposition: attachment; filename="freshrss_' . Minz_Session::param('currentUser', '_') . '_' . $day . '_export.zip"');
 		readfile($zip_file);
 		readfile($zip_file);
 		unlink($zip_file);
 		unlink($zip_file);
 	}
 	}

+ 2 - 0
app/Controllers/subscriptionController.php

@@ -33,6 +33,8 @@ class FreshRSS_subscription_Controller extends Minz_ActionController {
 		                        @filemtime(PUBLIC_PATH . '/scripts/category.js')));
 		                        @filemtime(PUBLIC_PATH . '/scripts/category.js')));
 		Minz_View::prependTitle(_t('sub.title') . ' · ');
 		Minz_View::prependTitle(_t('sub.title') . ' · ');
 
 
+		$this->view->onlyFeedsWithError = Minz_Request::paramTernary('error');
+
 		$id = Minz_Request::param('id');
 		$id = Minz_Request::param('id');
 		if ($id !== false) {
 		if ($id !== false) {
 			$feedDAO = FreshRSS_Factory::createFeedDao();
 			$feedDAO = FreshRSS_Factory::createFeedDao();

+ 7 - 5
app/Models/Auth.php

@@ -233,9 +233,11 @@ class FreshRSS_FormAuth {
 
 
 		$token_file = DATA_PATH . '/tokens/' . $token . '.txt';
 		$token_file = DATA_PATH . '/tokens/' . $token . '.txt';
 		$mtime = @filemtime($token_file);
 		$mtime = @filemtime($token_file);
-		if ($mtime + 2629744 < time()) {
-			// Token has expired (> 1 month) or does not exist.
-			// TODO: 1 month -> use a configuration instead
+		$conf = Minz_Configuration::get('system');
+		$limits = $conf->limits;
+		$cookie_duration = empty($limits['cookie_duration']) ? 2592000 : $limits['cookie_duration'];
+		if ($mtime + $cookie_duration < time()) {
+			// Token has expired (> cookie_duration) or does not exist.
 			@unlink($token_file);
 			@unlink($token_file);
 			return array();
 			return array();
 		}
 		}
@@ -256,7 +258,7 @@ class FreshRSS_FormAuth {
 		}
 		}
 
 
 		$limits = $conf->limits;
 		$limits = $conf->limits;
-		$cookie_duration = empty($limits['cookie_duration']) ? 2629744 : $limits['cookie_duration'];
+		$cookie_duration = empty($limits['cookie_duration']) ? 2592000 : $limits['cookie_duration'];
 		$expire = time() + $cookie_duration;
 		$expire = time() + $cookie_duration;
 		Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire);
 		Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire);
 		return $token;
 		return $token;
@@ -277,7 +279,7 @@ class FreshRSS_FormAuth {
 	public static function purgeTokens() {
 	public static function purgeTokens() {
 		$conf = Minz_Configuration::get('system');
 		$conf = Minz_Configuration::get('system');
 		$limits = $conf->limits;
 		$limits = $conf->limits;
-		$cookie_duration = empty($limits['cookie_duration']) ? 2629744 : $limits['cookie_duration'];
+		$cookie_duration = empty($limits['cookie_duration']) ? 2592000 : $limits['cookie_duration'];
 		$oldest = time() - $cookie_duration;
 		$oldest = time() - $cookie_duration;
 		foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) {
 		foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) {
 			// $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7
 			// $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7

+ 8 - 0
app/Models/BooleanSearch.php

@@ -45,6 +45,14 @@ class FreshRSS_BooleanSearch {
 		return $this->searches;
 		return $this->searches;
 	}
 	}
 
 
+	public function add($search) {
+		if ($search instanceof FreshRSS_Search) {
+			$this->searches[] = $search;
+			return $search;
+		}
+		return null;
+	}
+
 	public function __toString() {
 	public function __toString() {
 		return $this->getRawInput();
 		return $this->getRawInput();
 	}
 	}

+ 3 - 0
app/Models/ConfigurationSetter.php

@@ -335,6 +335,9 @@ class FreshRSS_ConfigurationSetter {
 	private function _limits(&$data, $values) {
 	private function _limits(&$data, $values) {
 		$max_small_int = 16384;
 		$max_small_int = 16384;
 		$limits_keys = array(
 		$limits_keys = array(
+			'cookie_duration' => array(
+				'min' => 0,
+			),
 			'cache_duration' => array(
 			'cache_duration' => array(
 				'min' => 0,
 				'min' => 0,
 			),
 			),

+ 11 - 2
app/Models/EntryDAO.php

@@ -671,6 +671,15 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
 		return isset($entries[0]) ? $entries[0] : null;
 		return isset($entries[0]) ? $entries[0] : null;
 	}
 	}
 
 
+	public function searchIdByGuid($id_feed, $guid) {
+		$sql = 'SELECT id FROM `' . $this->prefix . 'entry` WHERE id_feed=? AND guid=?';
+		$stm = $this->bd->prepare($sql);
+		$values = array($id_feed, $guid);
+		$stm->execute($values);
+		$res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
+		return isset($res[0]) ? $res[0] : null;
+	}
+
 	protected function sqlConcat($s1, $s2) {
 	protected function sqlConcat($s1, $s2) {
 		return 'CONCAT(' . $s1 . ',' . $s2 . ')';	//MySQL
 		return 'CONCAT(' . $s1 . ',' . $s2 . ')';	//MySQL
 	}
 	}
@@ -912,8 +921,8 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
 		return self::daoToEntries($stm->fetchAll(PDO::FETCH_ASSOC));
 		return self::daoToEntries($stm->fetchAll(PDO::FETCH_ASSOC));
 	}
 	}
 
 
-	public function listIdsWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filters = null, $date_min = 0) {	//For API
-		list($values, $sql) = $this->sqlListWhere($type, $id, $state, $order, $limit, $firstId, $filters, $date_min);
+	public function listIdsWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filters = null) {	//For API
+		list($values, $sql) = $this->sqlListWhere($type, $id, $state, $order, $limit, $firstId, $filters);
 
 
 		$stm = $this->bd->prepare($sql);
 		$stm = $this->bd->prepare($sql);
 		$stm->execute($values);
 		$stm->execute($values);

+ 11 - 10
app/Models/Feed.php

@@ -424,7 +424,7 @@ class FreshRSS_Feed extends Minz_Model {
 			$author_names = '';
 			$author_names = '';
 			if (is_array($authors)) {
 			if (is_array($authors)) {
 				foreach ($authors as $author) {
 				foreach ($authors as $author) {
-					$author_names .= html_only_entity_decode(strip_tags($author->name == '' ? $author->email : $author->name)) . '; ';
+					$author_names .= escapeToUnicodeAlternative(strip_tags($author->name == '' ? $author->email : $author->name), true) . '; ';
 				}
 				}
 			}
 			}
 			$author_names = substr($author_names, 0, -2);
 			$author_names = substr($author_names, 0, -2);
@@ -498,7 +498,7 @@ class FreshRSS_Feed extends Minz_Model {
 		@unlink($this->lockPath);
 		@unlink($this->lockPath);
 	}
 	}
 
 
-	//<PubSubHubbub>
+	//<WebSub>
 
 
 	public function pubSubHubbubEnabled() {
 	public function pubSubHubbubEnabled() {
 		$url = $this->selfUrl ? $this->selfUrl : $this->url;
 		$url = $this->selfUrl ? $this->selfUrl : $this->url;
@@ -534,13 +534,13 @@ class FreshRSS_Feed extends Minz_Model {
 			if ($hubFile = @file_get_contents($hubFilename)) {
 			if ($hubFile = @file_get_contents($hubFilename)) {
 				$hubJson = json_decode($hubFile, true);
 				$hubJson = json_decode($hubFile, true);
 				if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) {
 				if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) {
-					$text = 'Invalid JSON for PubSubHubbub: ' . $this->url;
+					$text = 'Invalid JSON for WebSub: ' . $this->url;
 					Minz_Log::warning($text);
 					Minz_Log::warning($text);
 					Minz_Log::warning($text, PSHB_LOG);
 					Minz_Log::warning($text, PSHB_LOG);
 					return false;
 					return false;
 				}
 				}
 				if ((!empty($hubJson['lease_end'])) && ($hubJson['lease_end'] < (time() + (3600 * 23)))) {	//TODO: Make a better policy
 				if ((!empty($hubJson['lease_end'])) && ($hubJson['lease_end'] < (time() + (3600 * 23)))) {	//TODO: Make a better policy
-					$text = 'PubSubHubbub lease ends at '
+					$text = 'WebSub lease ends at '
 						. date('c', empty($hubJson['lease_end']) ? time() : $hubJson['lease_end'])
 						. date('c', empty($hubJson['lease_end']) ? time() : $hubJson['lease_end'])
 						. ' and needs renewal: ' . $this->url;
 						. ' and needs renewal: ' . $this->url;
 					Minz_Log::warning($text);
 					Minz_Log::warning($text);
@@ -560,7 +560,7 @@ class FreshRSS_Feed extends Minz_Model {
 				file_put_contents($hubFilename, json_encode($hubJson));
 				file_put_contents($hubFilename, json_encode($hubJson));
 				@mkdir(PSHB_PATH . '/keys/');
 				@mkdir(PSHB_PATH . '/keys/');
 				file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', base64url_encode($this->selfUrl));
 				file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', base64url_encode($this->selfUrl));
-				$text = 'PubSubHubbub prepared for ' . $this->url;
+				$text = 'WebSub prepared for ' . $this->url;
 				Minz_Log::debug($text);
 				Minz_Log::debug($text);
 				Minz_Log::debug($text, PSHB_LOG);
 				Minz_Log::debug($text, PSHB_LOG);
 			}
 			}
@@ -579,17 +579,17 @@ class FreshRSS_Feed extends Minz_Model {
 			$hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($url) . '/!hub.json';
 			$hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($url) . '/!hub.json';
 			$hubFile = @file_get_contents($hubFilename);
 			$hubFile = @file_get_contents($hubFilename);
 			if ($hubFile === false) {
 			if ($hubFile === false) {
-				Minz_Log::warning('JSON not found for PubSubHubbub: ' . $this->url);
+				Minz_Log::warning('JSON not found for WebSub: ' . $this->url);
 				return false;
 				return false;
 			}
 			}
 			$hubJson = json_decode($hubFile, true);
 			$hubJson = json_decode($hubFile, true);
 			if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key']) || empty($hubJson['hub'])) {
 			if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key']) || empty($hubJson['hub'])) {
-				Minz_Log::warning('Invalid JSON for PubSubHubbub: ' . $this->url);
+				Minz_Log::warning('Invalid JSON for WebSub: ' . $this->url);
 				return false;
 				return false;
 			}
 			}
 			$callbackUrl = checkUrl(Minz_Request::getBaseUrl() . '/api/pshb.php?k=' . $hubJson['key']);
 			$callbackUrl = checkUrl(Minz_Request::getBaseUrl() . '/api/pshb.php?k=' . $hubJson['key']);
 			if ($callbackUrl == '') {
 			if ($callbackUrl == '') {
-				Minz_Log::warning('Invalid callback for PubSubHubbub: ' . $this->url);
+				Minz_Log::warning('Invalid callback for WebSub: ' . $this->url);
 				return false;
 				return false;
 			}
 			}
 			if (!$state) {	//unsubscribe
 			if (!$state) {	//unsubscribe
@@ -618,7 +618,8 @@ class FreshRSS_Feed extends Minz_Model {
 			$response = curl_exec($ch);
 			$response = curl_exec($ch);
 			$info = curl_getinfo($ch);
 			$info = curl_getinfo($ch);
 
 
-			Minz_Log::warning('PubSubHubbub ' . ($state ? 'subscribe' : 'unsubscribe') . ' to ' . $url .
+			Minz_Log::warning('WebSub ' . ($state ? 'subscribe' : 'unsubscribe') . ' to ' . $url .
+				' via hub ' . $hubJson['hub'] .
 				' with callback ' . $callbackUrl . ': ' . $info['http_code'] . ' ' . $response, PSHB_LOG);
 				' with callback ' . $callbackUrl . ': ' . $info['http_code'] . ' ' . $response, PSHB_LOG);
 
 
 			if (substr($info['http_code'], 0, 1) == '2') {
 			if (substr($info['http_code'], 0, 1) == '2') {
@@ -633,5 +634,5 @@ class FreshRSS_Feed extends Minz_Model {
 		return false;
 		return false;
 	}
 	}
 
 
-	//</PubSubHubbub>
+	//</WebSub>
 }
 }

+ 7 - 1
app/Models/FeedDAO.php

@@ -465,9 +465,15 @@ UPDATE `{$this->prefix}feed`
 SQL;
 SQL;
 		$stm = $this->bd->prepare($sql);
 		$stm = $this->bd->prepare($sql);
 		if (!($stm && $stm->execute(array(':new_value' => FreshRSS_Feed::TTL_DEFAULT, ':old_value' => -2)))) {
 		if (!($stm && $stm->execute(array(':new_value' => FreshRSS_Feed::TTL_DEFAULT, ':old_value' => -2)))) {
+			$info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
+			Minz_Log::error('SQL warning updateTTL 1: ' . $info[2] . ' ' . $sql);
+
 			$sql2 = 'ALTER TABLE `' . $this->prefix . 'feed` ADD COLUMN ttl INT NOT NULL DEFAULT ' . FreshRSS_Feed::TTL_DEFAULT;	//v0.7.3
 			$sql2 = 'ALTER TABLE `' . $this->prefix . 'feed` ADD COLUMN ttl INT NOT NULL DEFAULT ' . FreshRSS_Feed::TTL_DEFAULT;	//v0.7.3
 			$stm = $this->bd->prepare($sql2);
 			$stm = $this->bd->prepare($sql2);
-			$stm->execute();
+			if (!($stm && $stm->execute())) {
+				$info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
+				Minz_Log::error('SQL error updateTTL 2: ' . $info[2] . ' ' . $sql2);
+			}
 		} else {
 		} else {
 			$stm->execute(array(':new_value' => -3600, ':old_value' => -1));
 			$stm->execute(array(':new_value' => -3600, ':old_value' => -1));
 		}
 		}

+ 8 - 0
app/Models/Search.php

@@ -73,10 +73,18 @@ class FreshRSS_Search {
 		return $this->min_date;
 		return $this->min_date;
 	}
 	}
 
 
+	public function setMinDate($value) {
+		return $this->min_date = $value;
+	}
+
 	public function getMaxDate() {
 	public function getMaxDate() {
 		return $this->max_date;
 		return $this->max_date;
 	}
 	}
 
 
+	public function setMaxDate($value) {
+		return $this->max_date = $value;
+	}
+
 	public function getMinPubdate() {
 	public function getMinPubdate() {
 		return $this->min_pubdate;
 		return $this->min_pubdate;
 	}
 	}

+ 1 - 1
app/Models/TagDAO.php

@@ -266,7 +266,7 @@ class FreshRSS_TagDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
 		if (is_array($entries) && count($entries) > 0) {
 		if (is_array($entries) && count($entries) > 0) {
 			$sql .= ' AND et.id_entry IN (' . str_repeat('?,', count($entries) - 1). '?)';
 			$sql .= ' AND et.id_entry IN (' . str_repeat('?,', count($entries) - 1). '?)';
 			foreach ($entries as $entry) {
 			foreach ($entries as $entry) {
-				$values[] = $entry->id();
+				$values[] = is_array($entry) ? $entry['id'] : $entry->id();
 			}
 			}
 		}
 		}
 		$stm = $this->bd->prepare($sql);
 		$stm = $this->bd->prepare($sql);

+ 21 - 17
app/i18n/cz/admin.php

@@ -67,8 +67,8 @@ return array(
 			'ok' => 'Máte rozšíření JSON.',
 			'ok' => 'Máte rozšíření JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Nemáte framework Minz.',
 			'nok' => 'Nemáte framework Minz.',
@@ -106,16 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Author',	//TODO - Translation
+		'community' => 'Available community extensions',	//TODO - Translation
+		'description' => 'Description',	//TODO - Translation
 		'disabled' => 'Vypnuto',
 		'disabled' => 'Vypnuto',
 		'empty_list' => 'Není naistalováno žádné rozšíření',
 		'empty_list' => 'Není naistalováno žádné rozšíření',
 		'enabled' => 'Zapnuto',
 		'enabled' => 'Zapnuto',
+		'latest' => 'Installed',	//TODO - Translation
+		'name' => 'Name',	//TODO - Translation
 		'no_configure_view' => 'Toto rozšíření nemá žádné možnosti nastavení.',
 		'no_configure_view' => 'Toto rozšíření nemá žádné možnosti nastavení.',
 		'system' => array(
 		'system' => array(
 			'_' => 'Systémová rozšíření',
 			'_' => 'Systémová rozšíření',
 			'no_rights' => 'Systémová rozšíření (na ně nemáte oprávnění)',
 			'no_rights' => 'Systémová rozšíření (na ně nemáte oprávnění)',
 		),
 		),
 		'title' => 'Rozšíření',
 		'title' => 'Rozšíření',
+		'update' => 'Update available',	//TODO - Translation
 		'user' => 'Uživatelská rozšíření',
 		'user' => 'Uživatelská rozšíření',
+		'version' => 'Version',	//TODO - Translation
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistika',
 		'_' => 'Statistika',
@@ -150,22 +157,19 @@ return array(
 		'top_feed' => 'Top ten kanálů',
 		'top_feed' => 'Top ten kanálů',
 	),
 	),
 	'system' => array(
 	'system' => array(
-		'_' => 'System configuration', // @todo translate
-		'auto-update-url' => 'Auto-update server URL', // @todo translate
-		'instance-name' => 'Instance name', // @todo translate
-		'max-categories' => 'Categories per user limit', // @todo translate
-		'max-feeds' => 'Feeds per user limit', // @todo translate
+		'_' => 'System configuration', //TODO - Translation
+		'auto-update-url' => 'Auto-update server URL', //TODO - Translation
+		'cookie-duration' => array(
+			'help' => 'in seconds', //TODO - Translation
+			'number' => 'Duration to keep logged in', //TODO - Translation
+		),
+		'instance-name' => 'Instance name', //TODO - Translation
+		'max-categories' => 'Categories per user limit', //TODO - Translation
+		'max-feeds' => 'Feeds per user limit', //TODO - Translation
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 znamená žádná omezení účtu',
 			'help' => '0 znamená žádná omezení účtu',
 			'number' => 'Maximální počet účtů',
 			'number' => 'Maximální počet účtů',
 		),
 		),
-		'community' => 'Available community extensions', // @todo translate
-		'name' => 'Name', // @todo translate
-		'version' => 'Version', // @todo translate
-		'description' => 'Description', // @todo translate
-		'author' => 'Author', // @todo translate
-		'latest' => 'Installed', // @todo translate
-		'update' => 'Update available', // @todo translate
 	),
 	),
 	'update' => array(
 	'update' => array(
 		'_' => 'Aktualizace systému',
 		'_' => 'Aktualizace systému',
@@ -179,15 +183,15 @@ return array(
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s článků (%s)',
 		'articles_and_size' => '%s článků (%s)',
 		'create' => 'Vytvořit nového uživatele',
 		'create' => 'Vytvořit nového uživatele',
-		'delete_users' => 'Delete user', // TODO
+		'delete_users' => 'Delete user',	//TODO - Translation
 		'language' => 'Jazyk',
 		'language' => 'Jazyk',
 		'number' => 'Zatím je vytvořen %d účet',
 		'number' => 'Zatím je vytvořen %d účet',
 		'numbers' => 'Zatím je vytvořeno %d účtů',
 		'numbers' => 'Zatím je vytvořeno %d účtů',
 		'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',
 		'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',
 		'password_format' => 'Alespoň 7 znaků',
 		'password_format' => 'Alespoň 7 znaků',
-		'selected' => 'Selected user', // TODO
+		'selected' => 'Selected user',	//TODO - Translation
 		'title' => 'Správa uživatelů',
 		'title' => 'Správa uživatelů',
-		'update_users' => 'Update user', // TODO
+		'update_users' => 'Update user',	//TODO - Translation
 		'user_list' => 'Seznam uživatelů',
 		'user_list' => 'Seznam uživatelů',
 		'username' => 'Přihlašovací jméno',
 		'username' => 'Přihlašovací jméno',
 		'users' => 'Uživatelé',
 		'users' => 'Uživatelé',

+ 28 - 25
app/i18n/cz/conf.php

@@ -19,7 +19,7 @@ return array(
 			'bottom_line' => 'Spodní řádek',
 			'bottom_line' => 'Spodní řádek',
 			'entry' => 'Ikony článků',
 			'entry' => 'Ikony článků',
 			'publication_date' => 'Datum vydání',
 			'publication_date' => 'Datum vydání',
-			'related_tags' => 'Související tagy',	//TODO
+			'related_tags' => 'Související tagy',	//TODO - Translation
 			'sharing' => 'Sdílení',
 			'sharing' => 'Sdílení',
 			'top_line' => 'Horní řádek',
 			'top_line' => 'Horní řádek',
 		),
 		),
@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'sekund (0 znamená žádný timeout)',
 			'seconds' => 'sekund (0 znamená žádný timeout)',
 			'timeout' => 'Timeout HTML5 notifikací',
 			'timeout' => 'Timeout HTML5 notifikací',
 		),
 		),
+		'show_nav_buttons' => 'Show the navigation buttons',	//TODO - Translation
 		'theme' => 'Vzhled',
 		'theme' => 'Vzhled',
 		'title' => 'Zobrazení',
 		'title' => 'Zobrazení',
 		'width' => array(
 		'width' => array(
@@ -37,12 +38,22 @@ return array(
 			'no_limit' => 'Bez limitu',
 			'no_limit' => 'Bez limitu',
 			'thin' => 'Tenká',
 			'thin' => 'Tenká',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	//TODO
+	),
+	'profile' => array(
+		'_' => 'Správa profilu',
+		'delete' => array(
+			'_' => 'Smazání účtu',
+			'warn' => 'Váš účet bude smazán spolu se všemi souvisejícími daty',
+		),
+		'password_api' => 'Password API<br /><small>(tzn. pro mobilní aplikace)</small>',
+		'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',
+		'password_format' => 'Alespoň 7 znaků',
+		'title' => 'Profil',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'Uživatelské dotazy',
 		'_' => 'Uživatelské dotazy',
 		'deprecated' => 'Tento dotaz již není platný. Odkazovaná kategorie nebo kanál byly smazány.',
 		'deprecated' => 'Tento dotaz již není platný. Odkazovaná kategorie nebo kanál byly smazány.',
-		'display' => 'Display user query results', // TODO
+		'display' => 'Display user query results',	//TODO - Translation
 		'filter' => 'Filtr aplikován:',
 		'filter' => 'Filtr aplikován:',
 		'get_all' => 'Zobrazit všechny články',
 		'get_all' => 'Zobrazit všechny články',
 		'get_category' => 'Zobrazit "%s" kategorii',
 		'get_category' => 'Zobrazit "%s" kategorii',
@@ -53,7 +64,7 @@ return array(
 		'number' => 'Dotaz n°%d',
 		'number' => 'Dotaz n°%d',
 		'order_asc' => 'Zobrazit nejdříve nejstarší články',
 		'order_asc' => 'Zobrazit nejdříve nejstarší články',
 		'order_desc' => 'Zobrazit nejdříve nejnovější články',
 		'order_desc' => 'Zobrazit nejdříve nejnovější články',
-		'remove' => 'Remove user query', // TODO
+		'remove' => 'Remove user query',	//TODO - Translation
 		'search' => 'Hledat "%s"',
 		'search' => 'Hledat "%s"',
 		'state_0' => 'Zobrazit všechny články',
 		'state_0' => 'Zobrazit všechny články',
 		'state_1' => 'Zobrazit přečtené články',
 		'state_1' => 'Zobrazit přečtené články',
@@ -73,31 +84,19 @@ return array(
 		'state_15' => 'Zobrazit všechny články',
 		'state_15' => 'Zobrazit všechny články',
 		'title' => 'Uživatelské dotazy',
 		'title' => 'Uživatelské dotazy',
 	),
 	),
-	'profile' => array(
-		'_' => 'Správa profilu',
-		'delete' => array(
-			'_' => 'Smazání účtu',
-			'warn' => 'Váš účet bude smazán spolu se všemi souvisejícími daty',
-		),
-		'password_api' => 'Password API<br /><small>(tzn. pro mobilní aplikace)</small>',
-		'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',
-		'password_format' => 'Alespoň 7 znaků',
-		'title' => 'Profil',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Čtení',
 		'_' => 'Čtení',
 		'after_onread' => 'Po “označit vše jako přečtené”,',
 		'after_onread' => 'Po “označit vše jako přečtené”,',
 		'articles_per_page' => 'Počet článků na stranu',
 		'articles_per_page' => 'Počet článků na stranu',
 		'auto_load_more' => 'Načítat další články dole na stránce',
 		'auto_load_more' => 'Načítat další články dole na stránce',
 		'auto_remove_article' => 'Po přečtení články schovat',
 		'auto_remove_article' => 'Po přečtení články schovat',
-		'mark_updated_article_unread' => 'Označte aktualizované položky jako nepřečtené',
 		'confirm_enabled' => 'Vyžadovat potvrzení pro akci “označit vše jako přečtené”',
 		'confirm_enabled' => 'Vyžadovat potvrzení pro akci “označit vše jako přečtené”',
 		'display_articles_unfolded' => 'Ve výchozím stavu zobrazovat články otevřené',
 		'display_articles_unfolded' => 'Ve výchozím stavu zobrazovat články otevřené',
 		'display_categories_unfolded' => 'Ve výchozím stavu zobrazovat kategorie zavřené',
 		'display_categories_unfolded' => 'Ve výchozím stavu zobrazovat kategorie zavřené',
 		'hide_read_feeds' => 'Schovat kategorie a kanály s nulovým počtem nepřečtených článků (nefunguje s nastavením “Zobrazit všechny články”)',
 		'hide_read_feeds' => 'Schovat kategorie a kanály s nulovým počtem nepřečtených článků (nefunguje s nastavením “Zobrazit všechny články”)',
 		'img_with_lazyload' => 'Použít "lazy load" mód pro načítaní obrázků',
 		'img_with_lazyload' => 'Použít "lazy load" mód pro načítaní obrázků',
-		'sides_close_article' => 'Clicking outside of article text area closes the article',	//TODO
 		'jump_next' => 'skočit na další nepřečtený (kanál nebo kategorii)',
 		'jump_next' => 'skočit na další nepřečtený (kanál nebo kategorii)',
+		'mark_updated_article_unread' => 'Označte aktualizované položky jako nepřečtené',
 		'number_divided_when_reader' => 'V režimu “Čtení” děleno dvěma.',
 		'number_divided_when_reader' => 'V režimu “Čtení” děleno dvěma.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'když je otevřen původní web s článkem',
 			'article_open_on_website' => 'když je otevřen původní web s článkem',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => 'Zobrazit všechny články',
 			'all_articles' => 'Zobrazit všechny články',
 			'unread' => 'Zobrazit jen nepřečtené',
 			'unread' => 'Zobrazit jen nepřečtené',
 		),
 		),
+		'sides_close_article' => 'Clicking outside of article text area closes the article',	//TODO - Translation
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Řazení',
 			'_' => 'Řazení',
 			'newer_first' => 'Nejdříve nejnovější',
 			'newer_first' => 'Nejdříve nejnovější',
@@ -128,7 +128,7 @@ return array(
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Sdílení',
 		'_' => 'Sdílení',
-		'add' => 'Add a sharing method', // TODO
+		'add' => 'Add a sharing method',	//TODO - Translation
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -136,7 +136,7 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'more_information' => 'Více informací',
 		'more_information' => 'Více informací',
 		'print' => 'Tisk',
 		'print' => 'Tisk',
-		'remove' => 'Remove sharing method', // TODO
+		'remove' => 'Remove sharing method',	//TODO - Translation
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
 		'share_name' => 'Jméno pro zobrazení',
 		'share_name' => 'Jméno pro zobrazení',
 		'share_url' => 'Jakou URL použít pro sdílení',
 		'share_url' => 'Jakou URL použít pro sdílení',
@@ -153,27 +153,30 @@ return array(
 		'collapse_article' => 'Srolovat',
 		'collapse_article' => 'Srolovat',
 		'first_article' => 'Skočit na první článek',
 		'first_article' => 'Skočit na první článek',
 		'focus_search' => 'Hledání',
 		'focus_search' => 'Hledání',
-		'global_view' => 'Switch to global view', // TODO
+		'global_view' => 'Switch to global view',	//TODO - Translation
 		'help' => 'Zobrazit documentaci',
 		'help' => 'Zobrazit documentaci',
 		'javascript' => 'Pro použití zkratek musí být povolen JavaScript',
 		'javascript' => 'Pro použití zkratek musí být povolen JavaScript',
 		'last_article' => 'Skočit na poslední článek',
 		'last_article' => 'Skočit na poslední článek',
 		'load_more' => 'Načíst více článků',
 		'load_more' => 'Načíst více článků',
-		'mark_read' => 'Označit jako přečtené',
 		'mark_favorite' => 'Označit jako oblíbené',
 		'mark_favorite' => 'Označit jako oblíbené',
+		'mark_read' => 'Označit jako přečtené',
 		'navigation' => 'Navigace',
 		'navigation' => 'Navigace',
 		'navigation_help' => 'Pomocí přepínače "Shift" fungují navigační zkratky v rámci kanálů.<br/>Pomocí přepínače "Alt" fungují v rámci kategorií.',
 		'navigation_help' => 'Pomocí přepínače "Shift" fungují navigační zkratky v rámci kanálů.<br/>Pomocí přepínače "Alt" fungují v rámci kategorií.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => 'Skočit na další článek',
 		'next_article' => 'Skočit na další článek',
-		'normal_view' => 'Switch to normal view', // TODO
+		'normal_view' => 'Switch to normal view',	//TODO - Translation
 		'other_action' => 'Ostatní akce',
 		'other_action' => 'Ostatní akce',
 		'previous_article' => 'Skočit na předchozí článek',
 		'previous_article' => 'Skočit na předchozí článek',
-		'reading_view' => 'Switch to reading view', // TODO
-		'rss_view' => 'Open RSS view in a new tab', // TODO
+		'reading_view' => 'Switch to reading view',	//TODO - Translation
+		'rss_view' => 'Open RSS view in a new tab',	//TODO - Translation
 		'see_on_website' => 'Navštívit původní webovou stránku',
 		'see_on_website' => 'Navštívit původní webovou stránku',
 		'shift_for_all_read' => '+ <code>shift</code> označí vše jako přečtené',
 		'shift_for_all_read' => '+ <code>shift</code> označí vše jako přečtené',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => 'Zkratky',
 		'title' => 'Zkratky',
 		'user_filter' => 'Aplikovat uživatelské filtry',
 		'user_filter' => 'Aplikovat uživatelské filtry',
 		'user_filter_help' => 'Je-li nastaven pouze jeden filtr, bude použit. Další filtry jsou dostupné pomocí jejich čísla.',
 		'user_filter_help' => 'Je-li nastaven pouze jeden filtr, bude použit. Další filtry jsou dostupné pomocí jejich čísla.',
-		'views' => 'Views', // TODO
+		'views' => 'Views',	//TODO - Translation
 	),
 	),
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s článků (%s)',
 		'articles_and_size' => '%s článků (%s)',

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

@@ -50,11 +50,15 @@ return array(
 		'no_zip_extension' => 'Na serveru není naistalována podpora ZIP.',
 		'no_zip_extension' => 'Na serveru není naistalována podpora ZIP.',
 		'zip_error' => 'Během importu ZIP souboru došlo k chybě.',
 		'zip_error' => 'Během importu ZIP souboru došlo k chybě.',
 	),
 	),
+	'profile' => array(
+		'error' => 'Váš profil nelze změnit',
+		'updated' => 'Váš profil byl změněn',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Aktualizovat',
 		'actualize' => 'Aktualizovat',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	//TODO
-			'marked_unread' => 'The articles have been marked as unread.',	//TODO
+			'marked_read' => 'The selected articles have been marked as read.',	//TODO - Translation
+			'marked_unread' => 'The articles have been marked as unread.',	//TODO - Translation
 		),
 		),
 		'category' => array(
 		'category' => array(
 			'created' => 'Kategorie %s byla vytvořena.',
 			'created' => 'Kategorie %s byla vytvořena.',
@@ -76,7 +80,7 @@ return array(
 			'already_subscribed' => 'Již jste přihlášen k odběru <em>%s</em>',
 			'already_subscribed' => 'Již jste přihlášen k odběru <em>%s</em>',
 			'deleted' => 'Kanál byl smazán',
 			'deleted' => 'Kanál byl smazán',
 			'error' => 'Kanál nelze aktualizovat',
 			'error' => 'Kanál nelze aktualizovat',
-			'internal_problem' => 'RSS kanál nelze přidat. Pro detaily <a href="%s">zkontrolujte logy FreshRSS</a>.', // @todo
+			'internal_problem' => 'RSS kanál nelze přidat. Pro detaily <a href="%s">zkontrolujte logy FreshRSS</a>.',	//TODO - Translation
 			'invalid_url' => 'URL <em>%s</em> není platné',
 			'invalid_url' => 'URL <em>%s</em> není platné',
 			'n_actualized' => '%d kanálů bylo aktualizováno',
 			'n_actualized' => '%d kanálů bylo aktualizováno',
 			'n_entries_deleted' => '%d článků bylo smazáno',
 			'n_entries_deleted' => '%d článků bylo smazáno',
@@ -105,12 +109,8 @@ return array(
 			'error' => 'Uživatele %s nelze smazat',
 			'error' => 'Uživatele %s nelze smazat',
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated', // TODO
-			'error' => 'User %s has not been updated', // TODO
+			'_' => 'User %s has been updated',	//TODO - Translation
+			'error' => 'User %s has not been updated',	//TODO - Translation
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => 'Váš profil nelze změnit',
-		'updated' => 'Váš profil byl změněn',
-	),
 );
 );

+ 17 - 14
app/i18n/cz/gen.php

@@ -19,7 +19,7 @@ return array(
 		'see_website' => 'Navštívit WWW stránku',
 		'see_website' => 'Navštívit WWW stránku',
 		'submit' => 'Odeslat',
 		'submit' => 'Odeslat',
 		'truncate' => 'Smazat všechny články',
 		'truncate' => 'Smazat všechny články',
-		'update' => 'Update', // TODO
+		'update' => 'Update',	//TODO - Translation
 	),
 	),
 	'auth' => array(
 	'auth' => array(
 		'email' => 'Email',
 		'email' => 'Email',
@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\D\\u\\b\\e\\n',
 		'Apr' => '\\D\\u\\b\\e\\n',
-		'Aug' => '\\S\\r\\p\\e\\n',
-		'Dec' => '\\P\\r\\o\\s\\i\\n\\e\\c',
-		'Feb' => '\\Ú\\n\\o\\r',
-		'Jan' => '\\L\\e\\d\\e\\n',
-		'Jul' => '\\Č\\e\\r\\v\\e\\n\\e\\c',
-		'Jun' => '\\Č\\e\\r\\v\\e\\n',
-		'Mar' => '\\B\\ř\\e\\z\\e\\n',
-		'May' => '\\K\\v\\ě\\t\\e\\n',
-		'Nov' => '\\L\\i\\s\\t\\o\\p\\a\\d',
-		'Oct' => '\\Ř\\í\\j\\e\\n',
-		'Sep' => '\\Z\\á\\ř\\í',
 		'apr' => 'dub',
 		'apr' => 'dub',
 		'april' => 'Dub',
 		'april' => 'Dub',
+		'Aug' => '\\S\\r\\p\\e\\n',
 		'aug' => 'srp',
 		'aug' => 'srp',
 		'august' => 'Srp',
 		'august' => 'Srp',
 		'before_yesterday' => 'Předevčírem',
 		'before_yesterday' => 'Předevčírem',
+		'Dec' => '\\P\\r\\o\\s\\i\\n\\e\\c',
 		'dec' => 'pro',
 		'dec' => 'pro',
 		'december' => 'Pro',
 		'december' => 'Pro',
+		'Feb' => '\\Ú\\n\\o\\r',
 		'feb' => 'úno',
 		'feb' => 'úno',
 		'february' => 'Úno',
 		'february' => 'Úno',
 		'format_date' => 'j\\. %s Y',
 		'format_date' => 'j\\. %s Y',
 		'format_date_hour' => 'j\\. %s Y \\v H\\:i',
 		'format_date_hour' => 'j\\. %s Y \\v H\\:i',
 		'fri' => 'Pá',
 		'fri' => 'Pá',
+		'Jan' => '\\L\\e\\d\\e\\n',
 		'jan' => 'led',
 		'jan' => 'led',
 		'january' => 'Led',
 		'january' => 'Led',
+		'Jul' => '\\Č\\e\\r\\v\\e\\n\\e\\c',
 		'jul' => 'čvn',
 		'jul' => 'čvn',
 		'july' => 'Čvn',
 		'july' => 'Čvn',
+		'Jun' => '\\Č\\e\\r\\v\\e\\n',
 		'jun' => 'čer',
 		'jun' => 'čer',
 		'june' => 'Čer',
 		'june' => 'Čer',
 		'last_3_month' => 'Minulé tři měsíce',
 		'last_3_month' => 'Minulé tři měsíce',
@@ -78,17 +73,22 @@ return array(
 		'last_month' => 'Minulý měsíc',
 		'last_month' => 'Minulý měsíc',
 		'last_week' => 'Minulý týden',
 		'last_week' => 'Minulý týden',
 		'last_year' => 'Minulý rok',
 		'last_year' => 'Minulý rok',
+		'Mar' => '\\B\\ř\\e\\z\\e\\n',
 		'mar' => 'bře',
 		'mar' => 'bře',
 		'march' => 'Bře',
 		'march' => 'Bře',
+		'May' => '\\K\\v\\ě\\t\\e\\n',
 		'may' => 'Květen',
 		'may' => 'Květen',
 		'may_' => 'Kvě',
 		'may_' => 'Kvě',
 		'mon' => 'Po',
 		'mon' => 'Po',
 		'month' => 'měsíce',
 		'month' => 'měsíce',
+		'Nov' => '\\L\\i\\s\\t\\o\\p\\a\\d',
 		'nov' => 'lis',
 		'nov' => 'lis',
 		'november' => 'Lis',
 		'november' => 'Lis',
+		'Oct' => '\\Ř\\í\\j\\e\\n',
 		'oct' => 'říj',
 		'oct' => 'říj',
 		'october' => 'Říj',
 		'october' => 'Říj',
 		'sat' => 'So',
 		'sat' => 'So',
+		'Sep' => '\\Z\\á\\ř\\í',
 		'sep' => 'zář',
 		'sep' => 'zář',
 		'september' => 'Zář',
 		'september' => 'Zář',
 		'sun' => 'Ne',
 		'sun' => 'Ne',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -145,7 +146,7 @@ return array(
 		'sharing' => 'Sdílení',
 		'sharing' => 'Sdílení',
 		'shortcuts' => 'Zkratky',
 		'shortcuts' => 'Zkratky',
 		'stats' => 'Statistika',
 		'stats' => 'Statistika',
-		'system' => 'System configuration', // @todo translate
+		'system' => 'System configuration',	//TODO - Translation
 		'update' => 'Aktualizace',
 		'update' => 'Aktualizace',
 		'user_management' => 'Správa uživatelů',
 		'user_management' => 'Správa uživatelů',
 		'user_profile' => 'Profil',
 		'user_profile' => 'Profil',
@@ -160,7 +161,6 @@ return array(
 		'previous' => 'Předchozí',
 		'previous' => 'Předchozí',
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -168,9 +168,11 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'gnusocial' => 'GNU social',
 		'gnusocial' => 'GNU social',
 		'jdh' => 'Journal du hacker',
 		'jdh' => 'Journal du hacker',
+		'Known' => 'Known based sites',
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Tisk',
 		'print' => 'Tisk',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
@@ -186,6 +188,7 @@ return array(
 		'damn' => 'Sakra!',
 		'damn' => 'Sakra!',
 		'default_category' => 'Nezařazeno',
 		'default_category' => 'Nezařazeno',
 		'no' => 'Ne',
 		'no' => 'Ne',
+		'not_applicable' => 'Not available',	//TODO - Translation
 		'ok' => 'Ok!',
 		'ok' => 'Ok!',
 		'or' => 'nebo',
 		'or' => 'nebo',
 		'yes' => 'Ano',
 		'yes' => 'Ano',

+ 3 - 3
app/i18n/cz/index.php

@@ -40,7 +40,7 @@ return array(
 		'mark_all_read' => 'Označit vše jako přečtené',
 		'mark_all_read' => 'Označit vše jako přečtené',
 		'mark_cat_read' => 'Označit kategorii jako přečtenou',
 		'mark_cat_read' => 'Označit kategorii jako přečtenou',
 		'mark_feed_read' => 'Označit kanál jako přečtený',
 		'mark_feed_read' => 'Označit kanál jako přečtený',
-		'mark_selection_unread' => 'Mark selection as unread',	//TODO
+		'mark_selection_unread' => 'Mark selection as unread',	//TODO - Translation
 		'newer_first' => 'Nové nejdříve',
 		'newer_first' => 'Nové nejdříve',
 		'non-starred' => 'Zobrazit vše vyjma oblíbených',
 		'non-starred' => 'Zobrazit vše vyjma oblíbených',
 		'normal_view' => 'Normální',
 		'normal_view' => 'Normální',
@@ -53,11 +53,11 @@ return array(
 		'starred' => 'Zobrazit oblíbené',
 		'starred' => 'Zobrazit oblíbené',
 		'stats' => 'Statistika',
 		'stats' => 'Statistika',
 		'subscription' => 'Správa subskripcí',
 		'subscription' => 'Správa subskripcí',
-		'tags' => 'My labels',	//TODO
+		'tags' => 'My labels',	//TODO - Translation
 		'unread' => 'Zobrazovat nepřečtené',
 		'unread' => 'Zobrazovat nepřečtené',
 	),
 	),
 	'share' => 'Sdílet',
 	'share' => 'Sdílet',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Související tagy',	//TODO
+		'related' => 'Související tagy',	//TODO - Translation
 	),
 	),
 );
 );

+ 4 - 4
app/i18n/cz/install.php

@@ -24,8 +24,8 @@ return array(
 			'ok' => 'Nastavení databáze bylo uloženo.',
 			'ok' => 'Nastavení databáze bylo uloženo.',
 		),
 		),
 		'host' => 'Hostitel',
 		'host' => 'Hostitel',
-		'prefix' => 'Prefix tabulky',
 		'password' => 'Heslo',
 		'password' => 'Heslo',
+		'prefix' => 'Prefix tabulky',
 		'type' => 'Typ databáze',
 		'type' => 'Typ databáze',
 		'username' => 'Uživatel',
 		'username' => 'Uživatel',
 	),
 	),
@@ -45,7 +45,7 @@ return array(
 			'ok' => 'Máte rozšíření cURL.',
 			'ok' => 'Máte rozšíření cURL.',
 		),
 		),
 		'data' => array(
 		'data' => array(
-		'nok' => 'Zkontrolujte oprávnění adresáře <em>./data</em>. HTTP server musí mít do tohoto adresáře práva zápisu',
+			'nok' => 'Zkontrolujte oprávnění adresáře <em>./data</em>. HTTP server musí mít do tohoto adresáře práva zápisu',
 			'ok' => 'Oprávnění adresáře data jsou v pořádku.',
 			'ok' => 'Oprávnění adresáře data jsou v pořádku.',
 		),
 		),
 		'dom' => array(
 		'dom' => array(
@@ -69,8 +69,8 @@ return array(
 			'ok' => 'Máte doporučenou knihovnu pro parsování JSON.',
 			'ok' => 'Máte doporučenou knihovnu pro parsování JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Nemáte framework Minz.',
 			'nok' => 'Nemáte framework Minz.',

+ 23 - 16
app/i18n/cz/sub.php

@@ -2,13 +2,13 @@
 
 
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',// TODO
-		'title' => 'API',// TODO
+		'documentation' => 'Copy the following URL to use it within an external tool.',	//TODO - Translation
+		'title' => 'API',	//TODO - Translation
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
-		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',// TODO
-		'label' => 'Subscribe',// TODO
-		'title' => 'Bookmarklet',// TODO
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',	//TODO - Translation
+		'label' => 'Subscribe',	//TODO - Translation
+		'title' => 'Bookmarklet',	//TODO - Translation
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Kategorie',
 		'_' => 'Kategorie',
@@ -27,7 +27,7 @@ return array(
 			'password' => 'Heslo',
 			'password' => 'Heslo',
 			'username' => 'Přihlašovací jméno',
 			'username' => 'Přihlašovací jméno',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	//TODO
+		'clear_cache' => 'Always clear cache',	//TODO - Translation
 		'css_help' => 'Stáhne zkrácenou verzi RSS kanálů (pozor, náročnější na čas!)',
 		'css_help' => 'Stáhne zkrácenou verzi RSS kanálů (pozor, náročnější na čas!)',
 		'css_path' => 'Původní CSS soubor článku z webových stránek',
 		'css_path' => 'Původní CSS soubor článku z webových stránek',
 		'description' => 'Popis',
 		'description' => 'Popis',
@@ -36,30 +36,37 @@ return array(
 		'informations' => 'Informace',
 		'informations' => 'Informace',
 		'keep_history' => 'Zachovat tento minimální počet článků',
 		'keep_history' => 'Zachovat tento minimální počet článků',
 		'moved_category_deleted' => 'Po smazání kategorie budou v ní obsažené kanály automaticky přesunuty do <em>%s</em>.',
 		'moved_category_deleted' => 'Po smazání kategorie budou v ní obsažené kanály automaticky přesunuty do <em>%s</em>.',
-		'mute' => 'mute', // TODO
+		'mute' => 'mute',	//TODO - Translation
 		'no_selected' => 'Nejsou označeny žádné kanály.',
 		'no_selected' => 'Nejsou označeny žádné kanály.',
 		'number_entries' => '%d článků',
 		'number_entries' => '%d článků',
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility', // TODO
-			'archived' => 'Do not show (archived)', // TODO
+			'_' => 'Visibility',	//TODO - Translation
+			'archived' => 'Do not show (archived)',	//TODO - Translation
 			'main_stream' => 'Zobrazit ve “Všechny kanály”',
 			'main_stream' => 'Zobrazit ve “Všechny kanály”',
-			'normal' => 'Show in its category', // TODO
+			'normal' => 'Show in its category',	//TODO - Translation
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	//TODO
+		'websub' => 'Okamžité oznámení s WebSub',
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
+		'ssl_verify' => 'Verify SSL security',	//TODO - Translation
 		'stats' => 'Statistika',
 		'stats' => 'Statistika',
 		'think_to_add' => 'Můžete přidat kanály.',
 		'think_to_add' => 'Můžete přidat kanály.',
-		'timeout' => 'Timeout in seconds',	//TODO
+		'timeout' => 'Timeout in seconds',	//TODO - Translation
 		'title' => 'Název',
 		'title' => 'Název',
 		'title_add' => 'Přidat RSS kanál',
 		'title_add' => 'Přidat RSS kanál',
 		'ttl' => 'Neobnovovat častěji než',
 		'ttl' => 'Neobnovovat častěji než',
 		'url' => 'URL kanálu',
 		'url' => 'URL kanálu',
 		'validator' => 'Zkontrolovat platnost kanálu',
 		'validator' => 'Zkontrolovat platnost kanálu',
 		'website' => 'URL webové stránky',
 		'website' => 'URL webové stránky',
-		'pubsubhubbub' => 'Okamžité oznámení s PubSubHubbub',
 	),
 	),
 	'firefox' => array(
 	'firefox' => array(
 		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',// TODO
 		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',// TODO
-		'title' => 'Firefox feed reader',// TODO
+		'title' => 'Firefox feed reader',	//TODO - Translation
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export' => 'Export',
 		'export' => 'Export',
@@ -76,11 +83,11 @@ return array(
 		'bookmark' => 'Přihlásit (FreshRSS bookmark)',
 		'bookmark' => 'Přihlásit (FreshRSS bookmark)',
 		'import_export' => 'Import / export',
 		'import_export' => 'Import / export',
 		'subscription_management' => 'Správa subskripcí',
 		'subscription_management' => 'Správa subskripcí',
-		'subscription_tools' => 'Subscription tools',// TODO
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 	'title' => array(
 	'title' => array(
 		'_' => 'Správa subskripcí',
 		'_' => 'Správa subskripcí',
 		'feed_management' => 'Správa RSS kanálů',
 		'feed_management' => 'Správa RSS kanálů',
-		'subscription_tools' => 'Subscription tools',// TODO
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 );
 );

+ 12 - 8
app/i18n/de/admin.php

@@ -67,8 +67,8 @@ return array(
 			'ok' => 'Sie haben die JSON-Erweiterung.',
 			'ok' => 'Sie haben die JSON-Erweiterung.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Ihnen fehlt die mbstring-Bibliothek für Unicode.',	//TODO
-			'ok' => 'Sie haben die empfohlene mbstring-Bliothek für Unicode.',	//TODO
+			'nok' => 'Ihnen fehlt die mbstring-Bibliothek für Unicode.',
+			'ok' => 'Sie haben die empfohlene mbstring-Bliothek für Unicode.',
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Ihnen fehlt das Minz-Framework.',
 			'nok' => 'Ihnen fehlt das Minz-Framework.',
@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Autor',
+		'community' => 'Verfügbare Community Erweiterungen',
+		'description' => 'Beschreibungen',
 		'disabled' => 'Deaktiviert',
 		'disabled' => 'Deaktiviert',
 		'empty_list' => 'Es gibt keine installierte Erweiterung.',
 		'empty_list' => 'Es gibt keine installierte Erweiterung.',
 		'enabled' => 'Aktiviert',
 		'enabled' => 'Aktiviert',
+		'latest' => 'Installiert',
+		'name' => 'Name',
 		'no_configure_view' => 'Diese Erweiterung kann nicht konfiguriert werden.',
 		'no_configure_view' => 'Diese Erweiterung kann nicht konfiguriert werden.',
 		'system' => array(
 		'system' => array(
 			'_' => 'System-Erweiterungen',
 			'_' => 'System-Erweiterungen',
 			'no_rights' => 'System-Erweiterung (Sie haben keine Berechtigung dafür)',
 			'no_rights' => 'System-Erweiterung (Sie haben keine Berechtigung dafür)',
 		),
 		),
 		'title' => 'Erweiterungen',
 		'title' => 'Erweiterungen',
+		'update' => 'Update verfügbar',
 		'user' => 'Benutzer-Erweiterungen',
 		'user' => 'Benutzer-Erweiterungen',
-		'community' => 'Verfügbare Community Erweiterungen',
-		'name' => 'Name',
 		'version' => 'Version',
 		'version' => 'Version',
-		'description' => 'Beschreibungen',
-		'author' => 'Autor',
-		'latest' => 'Installiert',
-		'update' => 'Update verfügbar',
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistiken',
 		'_' => 'Statistiken',
@@ -162,6 +162,10 @@ return array(
 		'instance-name' => 'Dein Reader Name',
 		'instance-name' => 'Dein Reader Name',
 		'max-categories' => 'Anzahl erlaubter Kategorien pro Benutzer',
 		'max-categories' => 'Anzahl erlaubter Kategorien pro Benutzer',
 		'max-feeds' => 'Anzahl erlaubter Feeds pro Benutzer',
 		'max-feeds' => 'Anzahl erlaubter Feeds pro Benutzer',
+		'cookie-duration' => array(
+			'help' => 'in Sekunden',
+			'number' => 'Duration to keep logged in', // @todo translate
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 meint, dass es kein Account Limit gibt',
 			'help' => '0 meint, dass es kein Account Limit gibt',
 			'number' => 'Maximale Anzahl von Accounts',
 			'number' => 'Maximale Anzahl von Accounts',

+ 19 - 16
app/i18n/de/conf.php

@@ -19,7 +19,7 @@ return array(
 			'bottom_line' => 'Fußzeile',
 			'bottom_line' => 'Fußzeile',
 			'entry' => 'Artikel-Symbole',
 			'entry' => 'Artikel-Symbole',
 			'publication_date' => 'Datum der Veröffentlichung',
 			'publication_date' => 'Datum der Veröffentlichung',
-			'related_tags' => 'Verwandte Tags',	//TODO
+			'related_tags' => 'Verwandte Tags',
 			'sharing' => 'Teilen',
 			'sharing' => 'Teilen',
 			'top_line' => 'Kopfzeile',
 			'top_line' => 'Kopfzeile',
 		),
 		),
@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'Sekunden (0 bedeutet keine Zeitüberschreitung)',
 			'seconds' => 'Sekunden (0 bedeutet keine Zeitüberschreitung)',
 			'timeout' => 'Zeitüberschreitung für HTML5-Benachrichtigung',
 			'timeout' => 'Zeitüberschreitung für HTML5-Benachrichtigung',
 		),
 		),
+		'show_nav_buttons' => 'Zeige Navigations-Buttons',
 		'theme' => 'Erscheinungsbild',
 		'theme' => 'Erscheinungsbild',
 		'title' => 'Anzeige',
 		'title' => 'Anzeige',
 		'width' => array(
 		'width' => array(
@@ -37,7 +38,17 @@ return array(
 			'no_limit' => 'Keine Begrenzung',
 			'no_limit' => 'Keine Begrenzung',
 			'thin' => 'Klein',
 			'thin' => 'Klein',
 		),
 		),
-		'show_nav_buttons' => 'Zeige Navigations-Buttons',
+	),
+	'profile' => array(
+		'_' => 'Profil-Verwaltung',
+		'delete' => array(
+			'_' => 'Accountlöschung',
+			'warn' => 'Dein Account und alle damit bezogenen Daten werden gelöscht.',
+		),
+		'password_api' => 'Passwort-API<br /><small>(z. B. für mobile Anwendungen)</small>',
+		'password_form' => 'Passwort<br /><small>(für die Anmeldemethode per Webformular)</small>',
+		'password_format' => 'mindestens 7 Zeichen',
+		'title' => 'Profil',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'Benutzerabfragen',
 		'_' => 'Benutzerabfragen',
@@ -73,31 +84,19 @@ return array(
 		'state_15' => 'Alle Artikel anzeigen',
 		'state_15' => 'Alle Artikel anzeigen',
 		'title' => 'Benutzerabfragen',
 		'title' => 'Benutzerabfragen',
 	),
 	),
-	'profile' => array(
-		'_' => 'Profil-Verwaltung',
-		'delete' => array(
-			'_' => 'Accountlöschung',
-			'warn' => 'Dein Account und alle damit bezogenen Daten werden gelöscht.',
-		),
-		'password_api' => 'Passwort-API<br /><small>(z. B. für mobile Anwendungen)</small>',
-		'password_form' => 'Passwort<br /><small>(für die Anmeldemethode per Webformular)</small>',
-		'password_format' => 'mindestens 7 Zeichen',
-		'title' => 'Profil',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Lesen',
 		'_' => 'Lesen',
 		'after_onread' => 'Nach „Alle als gelesen markieren“,',
 		'after_onread' => 'Nach „Alle als gelesen markieren“,',
 		'articles_per_page' => 'Anzahl der Artikel pro Seite',
 		'articles_per_page' => 'Anzahl der Artikel pro Seite',
 		'auto_load_more' => 'Die nächsten Artikel am Seitenende laden',
 		'auto_load_more' => 'Die nächsten Artikel am Seitenende laden',
 		'auto_remove_article' => 'Artikel nach dem Lesen verstecken',
 		'auto_remove_article' => 'Artikel nach dem Lesen verstecken',
-		'mark_updated_article_unread' => 'Markieren Sie aktualisierte Artikel als ungelesen',
 		'confirm_enabled' => 'Bei der Aktion „Alle als gelesen markieren“ einen Bestätigungsdialog anzeigen',
 		'confirm_enabled' => 'Bei der Aktion „Alle als gelesen markieren“ einen Bestätigungsdialog anzeigen',
 		'display_articles_unfolded' => 'Artikel standardmäßig ausgeklappt zeigen',
 		'display_articles_unfolded' => 'Artikel standardmäßig ausgeklappt zeigen',
 		'display_categories_unfolded' => 'Kategorien standardmäßig eingeklappt zeigen',
 		'display_categories_unfolded' => 'Kategorien standardmäßig eingeklappt zeigen',
 		'hide_read_feeds' => 'Kategorien & Feeds ohne ungelesene Artikel verstecken (funktioniert nicht mit der Einstellung „Alle Artikel zeigen“)',
 		'hide_read_feeds' => 'Kategorien & Feeds ohne ungelesene Artikel verstecken (funktioniert nicht mit der Einstellung „Alle Artikel zeigen“)',
 		'img_with_lazyload' => 'Verwende die "träges Laden"-Methode zum Laden von Bildern',
 		'img_with_lazyload' => 'Verwende die "träges Laden"-Methode zum Laden von Bildern',
-		'sides_close_article' => 'Klick außerhalb des Artikel-Textes schließt den Artikel',
 		'jump_next' => 'springe zum nächsten ungelesenen Geschwisterelement (Feed oder Kategorie)',
 		'jump_next' => 'springe zum nächsten ungelesenen Geschwisterelement (Feed oder Kategorie)',
+		'mark_updated_article_unread' => 'Markieren Sie aktualisierte Artikel als ungelesen',
 		'number_divided_when_reader' => 'Geteilt durch 2 in der Lese-Ansicht.',
 		'number_divided_when_reader' => 'Geteilt durch 2 in der Lese-Ansicht.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'wenn der Artikel auf der Original-Webseite geöffnet wird',
 			'article_open_on_website' => 'wenn der Artikel auf der Original-Webseite geöffnet wird',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => 'Alle Artikel zeigen',
 			'all_articles' => 'Alle Artikel zeigen',
 			'unread' => 'Nur ungelesene zeigen',
 			'unread' => 'Nur ungelesene zeigen',
 		),
 		),
+		'sides_close_article' => 'Klick außerhalb des Artikel-Textes schließt den Artikel',
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Sortierreihenfolge',
 			'_' => 'Sortierreihenfolge',
 			'newer_first' => 'Neuere zuerst',
 			'newer_first' => 'Neuere zuerst',
@@ -158,10 +158,11 @@ return array(
 		'javascript' => 'JavaScript muss aktiviert sein, um Tastaturkürzel benutzen zu können',
 		'javascript' => 'JavaScript muss aktiviert sein, um Tastaturkürzel benutzen zu können',
 		'last_article' => 'Zum letzten Artikel springen',
 		'last_article' => 'Zum letzten Artikel springen',
 		'load_more' => 'Weitere Artikel laden',
 		'load_more' => 'Weitere Artikel laden',
-		'mark_read' => 'Als gelesen markieren',
 		'mark_favorite' => 'Als Favorit markieren',
 		'mark_favorite' => 'Als Favorit markieren',
+		'mark_read' => 'Als gelesen markieren',
 		'navigation' => 'Navigation',
 		'navigation' => 'Navigation',
 		'navigation_help' => 'Mit der "Umschalttaste" finden die Tastenkombination auf Feeds Anwendung.<br/>Mit der "Alt-Taste" finden die Tastenkombination auf Kategorien Anwendung.',
 		'navigation_help' => 'Mit der "Umschalttaste" finden die Tastenkombination auf Feeds Anwendung.<br/>Mit der "Alt-Taste" finden die Tastenkombination auf Kategorien Anwendung.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => 'Zum nächsten Artikel springen',
 		'next_article' => 'Zum nächsten Artikel springen',
 		'normal_view' => 'Wechsle zur normalen Ansicht',
 		'normal_view' => 'Wechsle zur normalen Ansicht',
 		'other_action' => 'Andere Aktionen',
 		'other_action' => 'Andere Aktionen',
@@ -170,6 +171,8 @@ return array(
 		'rss_view' => 'Öffne RSS Ansicht in neuem Tab',
 		'rss_view' => 'Öffne RSS Ansicht in neuem Tab',
 		'see_on_website' => 'Auf der Original-Webseite ansehen',
 		'see_on_website' => 'Auf der Original-Webseite ansehen',
 		'shift_for_all_read' => '+ <code>Umschalttaste</code>, um alle Artikel als gelesen zu markieren.',
 		'shift_for_all_read' => '+ <code>Umschalttaste</code>, um alle Artikel als gelesen zu markieren.',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => 'Tastenkombination',
 		'title' => 'Tastenkombination',
 		'user_filter' => 'Auf Benutzerfilter zugreifen',
 		'user_filter' => 'Auf Benutzerfilter zugreifen',
 		'user_filter_help' => 'Wenn es nur einen Benutzerfilter gibt, wird dieser verwendet. Ansonsten sind die Filter über ihre Nummer erreichbar.',
 		'user_filter_help' => 'Wenn es nur einen Benutzerfilter gibt, wird dieser verwendet. Ansonsten sind die Filter über ihre Nummer erreichbar.',

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

@@ -50,6 +50,10 @@ return array(
 		'no_zip_extension' => 'Die ZIP-Erweiterung ist auf Ihrem Server nicht vorhanden.',
 		'no_zip_extension' => 'Die ZIP-Erweiterung ist auf Ihrem Server nicht vorhanden.',
 		'zip_error' => 'Ein Fehler trat während des ZIP-Imports auf.',
 		'zip_error' => 'Ein Fehler trat während des ZIP-Imports auf.',
 	),
 	),
+	'profile' => array(
+		'error' => 'Ihr Profil kann nicht geändert werden',
+		'updated' => 'Ihr Profil ist geändert worden',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Aktualisieren',
 		'actualize' => 'Aktualisieren',
 		'articles' => array(
 		'articles' => array(
@@ -76,7 +80,7 @@ return array(
 			'already_subscribed' => 'Sie haben <em>%s</em> bereits abonniert',
 			'already_subscribed' => 'Sie haben <em>%s</em> bereits abonniert',
 			'deleted' => 'Der Feed ist gelöscht worden',
 			'deleted' => 'Der Feed ist gelöscht worden',
 			'error' => 'Der Feed kann nicht aktualisiert werden',
 			'error' => 'Der Feed kann nicht aktualisiert werden',
-			'internal_problem' => 'Der RSS-Feed konnte nicht hinzugefügt werden. Für Details <a href="%s">prüfen Sie die FreshRSS-Protokolle</a>.', // @todo
+			'internal_problem' => 'Der RSS-Feed konnte nicht hinzugefügt werden. Für Details <a href="%s">prüfen Sie die FreshRSS-Protokolle</a>.',
 			'invalid_url' => 'Die URL <em>%s</em> ist ungültig',
 			'invalid_url' => 'Die URL <em>%s</em> ist ungültig',
 			'n_actualized' => 'Die %d Feeds sind aktualisiert worden',
 			'n_actualized' => 'Die %d Feeds sind aktualisiert worden',
 			'n_entries_deleted' => 'Die %d Artikel sind gelöscht worden',
 			'n_entries_deleted' => 'Die %d Artikel sind gelöscht worden',
@@ -109,8 +113,4 @@ return array(
 			'error' => 'Benutzer %s wurde nicht aktualisiert',
 			'error' => 'Benutzer %s wurde nicht aktualisiert',
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => 'Ihr Profil kann nicht geändert werden',
-		'updated' => 'Ihr Profil ist geändert worden',
-	),
 );
 );

+ 13 - 11
app/i18n/de/gen.php

@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\A\\p\\r\\i\\l',
 		'Apr' => '\\A\\p\\r\\i\\l',
-		'Aug' => '\\A\\u\\g\\u\\s\\t',
-		'Dec' => '\\D\\e\\z\\e\\m\\b\\e\\r',
-		'Feb' => '\\F\\e\\b\\r\\u\\a\\r',
-		'Jan' => '\\J\\a\\n\\u\\a\\r',
-		'Jul' => '\\J\\u\\l\\i',
-		'Jun' => '\\J\\u\\n\\i',
-		'Mar' => '\\M\\ä\\r\\z',
-		'May' => '\\M\\a\\i',
-		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
-		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
-		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
 		'apr' => 'Apr',
 		'apr' => 'Apr',
 		'april' => 'April',
 		'april' => 'April',
+		'Aug' => '\\A\\u\\g\\u\\s\\t',
 		'aug' => 'Aug',
 		'aug' => 'Aug',
 		'august' => 'August',
 		'august' => 'August',
 		'before_yesterday' => 'Ältere Beiträge',
 		'before_yesterday' => 'Ältere Beiträge',
+		'Dec' => '\\D\\e\\z\\e\\m\\b\\e\\r',
 		'dec' => 'Dez',
 		'dec' => 'Dez',
 		'december' => 'Dezember',
 		'december' => 'Dezember',
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r',
 		'feb' => 'Feb',
 		'feb' => 'Feb',
 		'february' => 'Februar',
 		'february' => 'Februar',
 		'format_date' => 'd\\. %s Y',
 		'format_date' => 'd\\. %s Y',
 		'format_date_hour' => 'd\\. %s Y \\u\\m H\\:i',
 		'format_date_hour' => 'd\\. %s Y \\u\\m H\\:i',
 		'fri' => 'Fr',
 		'fri' => 'Fr',
+		'Jan' => '\\J\\a\\n\\u\\a\\r',
 		'jan' => 'Jan',
 		'jan' => 'Jan',
 		'january' => 'Januar',
 		'january' => 'Januar',
+		'Jul' => '\\J\\u\\l\\i',
 		'jul' => 'Jul',
 		'jul' => 'Jul',
 		'july' => 'Juli',
 		'july' => 'Juli',
+		'Jun' => '\\J\\u\\n\\i',
 		'jun' => 'Jun',
 		'jun' => 'Jun',
 		'june' => 'Juni',
 		'june' => 'Juni',
 		'last_3_month' => 'Letzte drei Monate',
 		'last_3_month' => 'Letzte drei Monate',
@@ -78,17 +73,22 @@ return array(
 		'last_month' => 'Letzter Monat',
 		'last_month' => 'Letzter Monat',
 		'last_week' => 'Letzte Woche',
 		'last_week' => 'Letzte Woche',
 		'last_year' => 'Letztes Jahr',
 		'last_year' => 'Letztes Jahr',
+		'Mar' => '\\M\\ä\\r\\z',
 		'mar' => 'Mär',
 		'mar' => 'Mär',
 		'march' => 'März',
 		'march' => 'März',
+		'May' => '\\M\\a\\i',
 		'may' => 'Mai',
 		'may' => 'Mai',
 		'may_' => 'Mai',
 		'may_' => 'Mai',
 		'mon' => 'Mo',
 		'mon' => 'Mo',
 		'month' => 'Monat(en)',
 		'month' => 'Monat(en)',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
 		'nov' => 'Nov',
 		'nov' => 'Nov',
 		'november' => 'November',
 		'november' => 'November',
+		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
 		'oct' => 'Okt',
 		'oct' => 'Okt',
 		'october' => 'Oktober',
 		'october' => 'Oktober',
 		'sat' => 'Sa',
 		'sat' => 'Sa',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
 		'sep' => 'Sep',
 		'sep' => 'Sep',
 		'september' => 'September',
 		'september' => 'September',
 		'sun' => 'So',
 		'sun' => 'So',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -171,6 +172,7 @@ return array(
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Drucken',
 		'print' => 'Drucken',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',

+ 2 - 2
app/i18n/de/index.php

@@ -53,11 +53,11 @@ return array(
 		'starred' => 'Nur Favoriten zeigen',
 		'starred' => 'Nur Favoriten zeigen',
 		'stats' => 'Statistiken',
 		'stats' => 'Statistiken',
 		'subscription' => 'Abonnementverwaltung',
 		'subscription' => 'Abonnementverwaltung',
-		'tags' => 'My labels',	//TODO
+		'tags' => 'My labels',	//TODO - Translation
 		'unread' => 'Nur ungelesene zeigen',
 		'unread' => 'Nur ungelesene zeigen',
 	),
 	),
 	'share' => 'Teilen',
 	'share' => 'Teilen',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Verwandte Tags',	//TODO
+		'related' => 'Verwandte Tags',
 	),
 	),
 );
 );

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

@@ -24,8 +24,8 @@ return array(
 			'ok' => 'Datenbank-Konfiguration ist gespeichert worden.',
 			'ok' => 'Datenbank-Konfiguration ist gespeichert worden.',
 		),
 		),
 		'host' => 'Host',
 		'host' => 'Host',
-		'prefix' => 'Tabellen-Präfix',
 		'password' => 'SQL-Password',
 		'password' => 'SQL-Password',
+		'prefix' => 'Tabellen-Präfix',
 		'type' => 'Datenbank-Typ',
 		'type' => 'Datenbank-Typ',
 		'username' => 'SQL-Nutzername',
 		'username' => 'SQL-Nutzername',
 	),
 	),

+ 8 - 1
app/i18n/de/sub.php

@@ -45,6 +45,14 @@ return array(
 			'main_stream' => 'In Haupt-Feeds zeigen',
 			'main_stream' => 'In Haupt-Feeds zeigen',
 			'normal' => 'Zeige in eigener Kategorie',
 			'normal' => 'Zeige in eigener Kategorie',
 		),
 		),
+		'websub' => 'Sofortbenachrichtigung mit WebSub',
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
 		'ssl_verify' => 'Überprüfe SSL Sicherheit',
 		'ssl_verify' => 'Überprüfe SSL Sicherheit',
 		'stats' => 'Statistiken',
 		'stats' => 'Statistiken',
 		'think_to_add' => 'Sie können Feeds hinzufügen.',
 		'think_to_add' => 'Sie können Feeds hinzufügen.',
@@ -55,7 +63,6 @@ return array(
 		'url' => 'Feed-URL',
 		'url' => 'Feed-URL',
 		'validator' => 'Überprüfen Sie die Gültigkeit des Feeds',
 		'validator' => 'Überprüfen Sie die Gültigkeit des Feeds',
 		'website' => 'Webseiten-URL',
 		'website' => 'Webseiten-URL',
-		'pubsubhubbub' => 'Sofortbenachrichtigung mit PubSubHubbub',
 	),
 	),
 	'firefox' => array(
 	'firefox' => array(
 		'documentation' => 'Folge den <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">hier</a> beschriebenen Schritten um FreshRSS zu Deiner Firefox RSS-Reader Liste hinzuzufügen.',
 		'documentation' => 'Folge den <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">hier</a> beschriebenen Schritten um FreshRSS zu Deiner Firefox RSS-Reader Liste hinzuzufügen.',

+ 10 - 6
app/i18n/en/admin.php

@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Author',
+		'community' => 'Available community extensions',
+		'description' => 'Description',
 		'disabled' => 'Disabled',
 		'disabled' => 'Disabled',
 		'empty_list' => 'There are no installed extensions',
 		'empty_list' => 'There are no installed extensions',
 		'enabled' => 'Enabled',
 		'enabled' => 'Enabled',
+		'latest' => 'Installed',
+		'name' => 'Name',
 		'no_configure_view' => 'This extension cannot be configured.',
 		'no_configure_view' => 'This extension cannot be configured.',
 		'system' => array(
 		'system' => array(
 			'_' => 'System extensions',
 			'_' => 'System extensions',
 			'no_rights' => 'System extension (you have no rights on it)',
 			'no_rights' => 'System extension (you have no rights on it)',
 		),
 		),
 		'title' => 'Extensions',
 		'title' => 'Extensions',
+		'update' => 'Update available',
 		'user' => 'User extensions',
 		'user' => 'User extensions',
-		'community' => 'Available community extensions',
-		'name' => 'Name',
 		'version' => 'Version',
 		'version' => 'Version',
-		'description' => 'Description',
-		'author' => 'Author',
-		'latest' => 'Installed',
-		'update' => 'Update available',
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistics',
 		'_' => 'Statistics',
@@ -162,6 +162,10 @@ return array(
 		'instance-name' => 'Instance name',
 		'instance-name' => 'Instance name',
 		'max-categories' => 'Categories per user limit',
 		'max-categories' => 'Categories per user limit',
 		'max-feeds' => 'Feeds per user limit',
 		'max-feeds' => 'Feeds per user limit',
+		'cookie-duration' => array(
+			'help' => 'in seconds',
+			'number' => 'Duration to keep logged in',
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 means that there is no account limit',
 			'help' => '0 means that there is no account limit',
 			'number' => 'Max number of accounts',
 			'number' => 'Max number of accounts',

+ 25 - 19
app/i18n/en/conf.php

@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'seconds (0 means no timeout)',
 			'seconds' => 'seconds (0 means no timeout)',
 			'timeout' => 'HTML5 notification timeout',
 			'timeout' => 'HTML5 notification timeout',
 		),
 		),
+		'show_nav_buttons' => 'Show the navigation buttons',
 		'theme' => 'Theme',
 		'theme' => 'Theme',
 		'title' => 'Display',
 		'title' => 'Display',
 		'width' => array(
 		'width' => array(
@@ -37,7 +38,17 @@ return array(
 			'no_limit' => 'No limit',
 			'no_limit' => 'No limit',
 			'thin' => 'Thin',
 			'thin' => 'Thin',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',
+	),
+	'profile' => array(
+		'_' => 'Profile management',
+		'delete' => array(
+			'_' => 'Account deletion',
+			'warn' => 'Your account and all related data will be deleted.',
+		),
+		'password_api' => 'API password<br /><small>(e.g., for mobile apps)</small>',
+		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
+		'password_format' => 'At least 7 characters',
+		'title' => 'Profile',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'User queries',
 		'_' => 'User queries',
@@ -73,31 +84,19 @@ return array(
 		'state_15' => 'Display all articles',
 		'state_15' => 'Display all articles',
 		'title' => 'User queries',
 		'title' => 'User queries',
 	),
 	),
-	'profile' => array(
-		'_' => 'Profile management',
-		'delete' => array(
-			'_' => 'Account deletion',
-			'warn' => 'Your account and all related data will be deleted.',
-		),
-		'password_api' => 'API password<br /><small>(e.g., for mobile apps)</small>',
-		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
-		'password_format' => 'At least 7 characters',
-		'title' => 'Profile',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Reading',
 		'_' => 'Reading',
 		'after_onread' => 'After “mark all as read”,',
 		'after_onread' => 'After “mark all as read”,',
 		'articles_per_page' => 'Number of articles per page',
 		'articles_per_page' => 'Number of articles per page',
 		'auto_load_more' => 'Load more articles at the page bottom',
 		'auto_load_more' => 'Load more articles at the page bottom',
 		'auto_remove_article' => 'Hide articles after reading',
 		'auto_remove_article' => 'Hide articles after reading',
-		'mark_updated_article_unread' => 'Mark updated articles as unread',
 		'confirm_enabled' => 'Display a confirmation dialog on “mark all as read” actions',
 		'confirm_enabled' => 'Display a confirmation dialog on “mark all as read” actions',
 		'display_articles_unfolded' => 'Show articles unfolded by default',
 		'display_articles_unfolded' => 'Show articles unfolded by default',
 		'display_categories_unfolded' => 'Show categories folded by default',
 		'display_categories_unfolded' => 'Show categories folded by default',
 		'hide_read_feeds' => 'Hide categories & feeds with no unread articles (does not work with “Show all articles” configuration)',
 		'hide_read_feeds' => 'Hide categories & feeds with no unread articles (does not work with “Show all articles” configuration)',
 		'img_with_lazyload' => 'Use "lazy load" mode to load pictures',
 		'img_with_lazyload' => 'Use "lazy load" mode to load pictures',
-		'sides_close_article' => 'Clicking outside of article text area closes the article',
 		'jump_next' => 'jump to next unread sibling (feed or category)',
 		'jump_next' => 'jump to next unread sibling (feed or category)',
+		'mark_updated_article_unread' => 'Mark updated articles as unread',
 		'number_divided_when_reader' => 'Divided by 2 in the reading view.',
 		'number_divided_when_reader' => 'Divided by 2 in the reading view.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'when article is opened on its original website',
 			'article_open_on_website' => 'when article is opened on its original website',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => 'Show all articles',
 			'all_articles' => 'Show all articles',
 			'unread' => 'Show only unread',
 			'unread' => 'Show only unread',
 		),
 		),
+		'sides_close_article' => 'Clicking outside of article text area closes the article',
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Sort order',
 			'_' => 'Sort order',
 			'newer_first' => 'Newest first',
 			'newer_first' => 'Newest first',
@@ -151,25 +151,31 @@ return array(
 		'auto_share_help' => 'If there is only one sharing mode, it is used. Otherwise, modes are accessible by their number.',
 		'auto_share_help' => 'If there is only one sharing mode, it is used. Otherwise, modes are accessible by their number.',
 		'close_dropdown' => 'Close menus',
 		'close_dropdown' => 'Close menus',
 		'collapse_article' => 'Collapse',
 		'collapse_article' => 'Collapse',
-		'first_article' => 'Skip to the first article',
+		'first_article' => 'Open the first article',
 		'focus_search' => 'Access search box',
 		'focus_search' => 'Access search box',
 		'global_view' => 'Switch to global view',
 		'global_view' => 'Switch to global view',
 		'help' => 'Display documentation',
 		'help' => 'Display documentation',
 		'javascript' => 'JavaScript must be enabled in order to use shortcuts',
 		'javascript' => 'JavaScript must be enabled in order to use shortcuts',
-		'last_article' => 'Skip to the last article',
+		'last_article' => 'Open the last article',
 		'load_more' => 'Load more articles',
 		'load_more' => 'Load more articles',
-		'mark_read' => 'Mark as read',
 		'mark_favorite' => 'Mark as favourite',
 		'mark_favorite' => 'Mark as favourite',
+		'mark_read' => 'Mark as read',
 		'navigation' => 'Navigation',
 		'navigation' => 'Navigation',
 		'navigation_help' => 'With the "Shift" modifier, navigation shortcuts apply on feeds.<br/>With the "Alt" modifier, navigation shortcuts apply on categories.',
 		'navigation_help' => 'With the "Shift" modifier, navigation shortcuts apply on feeds.<br/>With the "Alt" modifier, navigation shortcuts apply on categories.',
-		'next_article' => 'Skip to the next article',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',
+		'next_article' => 'Open the next article',
+		'other_action' => 'Other actions',
+		'previous_article' => 'Open the previous article',
+		'next_article' => 'Open the next article',
 		'normal_view' => 'Switch to normal view',
 		'normal_view' => 'Switch to normal view',
 		'other_action' => 'Other actions',
 		'other_action' => 'Other actions',
-		'previous_article' => 'Skip to the previous article',
+		'previous_article' => 'Open the previous article',
 		'reading_view' => 'Switch to reading view',
 		'reading_view' => 'Switch to reading view',
 		'rss_view' => 'Open RSS view in a new tab',
 		'rss_view' => 'Open RSS view in a new tab',
 		'see_on_website' => 'See on original website',
 		'see_on_website' => 'See on original website',
 		'shift_for_all_read' => '+ <code>shift</code> to mark all articles as read',
 		'shift_for_all_read' => '+ <code>shift</code> to mark all articles as read',
+		'skip_next_article' => 'Focus next without opening',
+		'skip_previous_article' => 'Focus previous without opening',
 		'title' => 'Shortcuts',
 		'title' => 'Shortcuts',
 		'user_filter' => 'Access user queries',
 		'user_filter' => 'Access user queries',
 		'user_filter_help' => 'If there is only one user query, it is used. Otherwise, queries are accessible by their number.',
 		'user_filter_help' => 'If there is only one user query, it is used. Otherwise, queries are accessible by their number.',

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

@@ -50,6 +50,10 @@ return array(
 		'no_zip_extension' => 'ZIP extension is not present on your server.',
 		'no_zip_extension' => 'ZIP extension is not present on your server.',
 		'zip_error' => 'An error occured during ZIP import.',
 		'zip_error' => 'An error occured during ZIP import.',
 	),
 	),
+	'profile' => array(
+		'error' => 'Your profile cannot be modified',
+		'updated' => 'Your profile has been modified',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Updating',
 		'actualize' => 'Updating',
 		'articles' => array(
 		'articles' => array(
@@ -109,8 +113,4 @@ return array(
 			'error' => 'User %s has not been updated',
 			'error' => 'User %s has not been updated',
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => 'Your profile cannot be modified',
-		'updated' => 'Your profile has been modified',
-	),
 );
 );

+ 13 - 11
app/i18n/en/gen.php

@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\A\\p\\r\\i\\l',
 		'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' => 'Apr.',
 		'apr' => 'Apr.',
 		'april' => 'April',
 		'april' => 'April',
+		'Aug' => '\\A\\u\\g\\u\\s\\t',
 		'aug' => 'Aug.',
 		'aug' => 'Aug.',
 		'august' => 'August',
 		'august' => 'August',
 		'before_yesterday' => 'Before yesterday',
 		'before_yesterday' => 'Before yesterday',
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
 		'dec' => 'Dec.',
 		'dec' => 'Dec.',
 		'december' => 'December',
 		'december' => 'December',
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',
 		'feb' => 'Feb.',
 		'feb' => 'Feb.',
 		'february' => 'February',
 		'february' => 'February',
 		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
 		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
 		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',
 		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',
 		'fri' => 'Fri',
 		'fri' => 'Fri',
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',
 		'jan' => 'Jan.',
 		'jan' => 'Jan.',
 		'january' => 'January',
 		'january' => 'January',
+		'Jul' => '\\J\\u\\l\\y',
 		'jul' => 'July',
 		'jul' => 'July',
 		'july' => 'July',
 		'july' => 'July',
+		'Jun' => '\\J\\u\\n\\e',
 		'jun' => 'June',
 		'jun' => 'June',
 		'june' => 'June',
 		'june' => 'June',
 		'last_3_month' => 'Last three months',
 		'last_3_month' => 'Last three months',
@@ -78,16 +73,21 @@ return array(
 		'last_month' => 'Last month',
 		'last_month' => 'Last month',
 		'last_week' => 'Last week',
 		'last_week' => 'Last week',
 		'last_year' => 'Last year',
 		'last_year' => 'Last year',
+		'Mar' => '\\M\\a\\r\\c\\h',
 		'mar' => 'Mar.',
 		'mar' => 'Mar.',
 		'march' => 'March',
 		'march' => 'March',
+		'May' => '\\M\\a\\y',
 		'may' => 'May',
 		'may' => 'May',
 		'may_' => 'May',
 		'may_' => 'May',
 		'mon' => 'Mon',
 		'mon' => 'Mon',
 		'month' => 'months',
 		'month' => 'months',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
 		'nov' => 'Nov.',
 		'nov' => 'Nov.',
 		'november' => 'November',
 		'november' => 'November',
+		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',
 		'oct' => 'Oct.',
 		'oct' => 'Oct.',
 		'october' => 'October',
 		'october' => 'October',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
 		'sat' => 'Sat',
 		'sat' => 'Sat',
 		'sep' => 'Sept.',
 		'sep' => 'Sept.',
 		'september' => 'September',
 		'september' => 'September',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -171,6 +172,7 @@ return array(
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Print',
 		'print' => 'Print',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',

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

@@ -58,6 +58,6 @@ return array(
 	),
 	),
 	'share' => 'Share',
 	'share' => 'Share',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Article tags',	//TODO
+		'related' => 'Article tags',
 	),
 	),
 );
 );

+ 3 - 3
app/i18n/en/install.php

@@ -24,8 +24,8 @@ return array(
 			'ok' => 'Database configuration has been saved.',
 			'ok' => 'Database configuration has been saved.',
 		),
 		),
 		'host' => 'Host',
 		'host' => 'Host',
-		'prefix' => 'Table prefix',
 		'password' => 'Database password',
 		'password' => 'Database password',
+		'prefix' => 'Table prefix',
 		'type' => 'Type of database',
 		'type' => 'Type of database',
 		'username' => 'Database username',
 		'username' => 'Database username',
 	),
 	),
@@ -69,8 +69,8 @@ return array(
 			'ok' => 'You have a recommended library to parse JSON.',
 			'ok' => 'You have a recommended library to parse JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',
+			'ok' => 'You have the recommended library mbstring for Unicode.',
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Cannot find the Minz framework.',
 			'nok' => 'Cannot find the Minz framework.',

+ 8 - 1
app/i18n/en/sub.php

@@ -45,6 +45,14 @@ return array(
 			'main_stream' => 'Show in main stream',
 			'main_stream' => 'Show in main stream',
 			'normal' => 'Show in its category',
 			'normal' => 'Show in its category',
 		),
 		),
+		'websub' => 'Instant notification with WebSub',
+		'show' => array(
+			'all' => 'Show all feeds',
+			'error' => 'Show only feeds with error',
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',
+		),
 		'ssl_verify' => 'Verify SSL security',
 		'ssl_verify' => 'Verify SSL security',
 		'stats' => 'Statistics',
 		'stats' => 'Statistics',
 		'think_to_add' => 'You may add some feeds.',
 		'think_to_add' => 'You may add some feeds.',
@@ -55,7 +63,6 @@ return array(
 		'url' => 'Feed URL',
 		'url' => 'Feed URL',
 		'validator' => 'Check the validity of the feed',
 		'validator' => 'Check the validity of the feed',
 		'website' => 'Website URL',
 		'website' => 'Website URL',
-		'pubsubhubbub' => 'Instant notification with PubSubHubbub',
 	),
 	),
 	'firefox' => array(
 	'firefox' => array(
 		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',
 		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',

+ 16 - 12
app/i18n/es/admin.php

@@ -67,8 +67,8 @@ return array(
 			'ok' => 'Dispones de la extensión JSON.',
 			'ok' => 'Dispones de la extensión JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'No se ha podido localizar el entorno Minz.',
 			'nok' => 'No se ha podido localizar el entorno Minz.',
@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Author',	//TODO - Translation
+		'community' => 'Available community extensions',	//TODO - Translation
+		'description' => 'Description',	//TODO - Translation
 		'disabled' => 'Desactivado',
 		'disabled' => 'Desactivado',
 		'empty_list' => 'No hay extensiones instaladas',
 		'empty_list' => 'No hay extensiones instaladas',
 		'enabled' => 'Activado',
 		'enabled' => 'Activado',
+		'latest' => 'Installed',	//TODO - Translation
+		'name' => 'Name',	//TODO - Translation
 		'no_configure_view' => 'Esta extensión no puede ser configurada.',
 		'no_configure_view' => 'Esta extensión no puede ser configurada.',
 		'system' => array(
 		'system' => array(
 			'_' => 'Sistema de extensiones',
 			'_' => 'Sistema de extensiones',
 			'no_rights' => 'Sistema de extensiones (careces de los permisos necesarios)',
 			'no_rights' => 'Sistema de extensiones (careces de los permisos necesarios)',
 		),
 		),
 		'title' => 'Extensiones',
 		'title' => 'Extensiones',
+		'update' => 'Update available',	//TODO - Translation
 		'user' => 'Extensiones de usuario',
 		'user' => 'Extensiones de usuario',
-		'community' => 'Available community extensions', // @todo translate
-		'name' => 'Name', // @todo translate
-		'version' => 'Version', // @todo translate
-		'description' => 'Description', // @todo translate
-		'author' => 'Author', // @todo translate
-		'latest' => 'Installed', // @todo translate
-		'update' => 'Update available', // @todo translate
+		'version' => 'Version',	//TODO - Translation
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Estadísticas',
 		'_' => 'Estadísticas',
@@ -162,6 +162,10 @@ return array(
 		'instance-name' => 'Nombre de la fuente',
 		'instance-name' => 'Nombre de la fuente',
 		'max-categories' => 'Límite de categorías por usuario',
 		'max-categories' => 'Límite de categorías por usuario',
 		'max-feeds' => 'Límite de fuentes por usuario',
 		'max-feeds' => 'Límite de fuentes por usuario',
+		'cookie-duration' => array(
+			'help' => 'in seconds', // @todo translate
+			'number' => 'Duration to keep logged in', // @todo translate
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 significa que no hay límite en la cuenta',
 			'help' => '0 significa que no hay límite en la cuenta',
 			'number' => 'Número máximo de cuentas',
 			'number' => 'Número máximo de cuentas',
@@ -179,15 +183,15 @@ return array(
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s articles (%s)',
 		'articles_and_size' => '%s articles (%s)',
 		'create' => 'Crear nuevo usuario',
 		'create' => 'Crear nuevo usuario',
-		'delete_users' => 'Delete user', // TODO
+		'delete_users' => 'Delete user',	//TODO - Translation
 		'language' => 'Idioma',
 		'language' => 'Idioma',
 		'number' => 'Hay %d cuenta creada',
 		'number' => 'Hay %d cuenta creada',
 		'numbers' => 'Hay %d cuentas creadas',
 		'numbers' => 'Hay %d cuentas creadas',
 		'password_form' => 'Contraseña<br /><small>(para el método de identificación por formulario web)</small>',
 		'password_form' => 'Contraseña<br /><small>(para el método de identificación por formulario web)</small>',
 		'password_format' => 'Mínimo de 7 caracteres',
 		'password_format' => 'Mínimo de 7 caracteres',
-		'selected' => 'Selected user', // TODO
+		'selected' => 'Selected user',	//TODO - Translation
 		'title' => 'Administrar usuarios',
 		'title' => 'Administrar usuarios',
-		'update_users' => 'Update user', // TODO
+		'update_users' => 'Update user',	//TODO - Translation
 		'user_list' => 'Lista de usuarios',
 		'user_list' => 'Lista de usuarios',
 		'username' => 'Nombre de usuario',
 		'username' => 'Nombre de usuario',
 		'users' => 'Usuarios',
 		'users' => 'Usuarios',

+ 28 - 25
app/i18n/es/conf.php

@@ -19,7 +19,7 @@ return array(
 			'bottom_line' => 'Línea inferior',
 			'bottom_line' => 'Línea inferior',
 			'entry' => 'Iconos de artículos',
 			'entry' => 'Iconos de artículos',
 			'publication_date' => 'Fecha de publicación',
 			'publication_date' => 'Fecha de publicación',
-			'related_tags' => 'Etiquetas relacionadas',	//TODO
+			'related_tags' => 'Etiquetas relacionadas',
 			'sharing' => 'Compartir',
 			'sharing' => 'Compartir',
 			'top_line' => 'Línea superior',
 			'top_line' => 'Línea superior',
 		),
 		),
@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'segundos (0 significa sin límite de espera)',
 			'seconds' => 'segundos (0 significa sin límite de espera)',
 			'timeout' => 'Notificación de fin de espera HTML5',
 			'timeout' => 'Notificación de fin de espera HTML5',
 		),
 		),
+		'show_nav_buttons' => 'Show the navigation buttons',	//TODO - Translation
 		'theme' => 'Tema',
 		'theme' => 'Tema',
 		'title' => 'Visualización',
 		'title' => 'Visualización',
 		'width' => array(
 		'width' => array(
@@ -37,12 +38,22 @@ return array(
 			'no_limit' => 'Sin límite',
 			'no_limit' => 'Sin límite',
 			'thin' => 'Estrecho',
 			'thin' => 'Estrecho',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	//TODO
+	),
+	'profile' => array(
+		'_' => 'Administración de perfiles',
+		'delete' => array(
+			'_' => 'Borrar cuenta',
+			'warn' => 'Tu cuenta y todos los datos asociados serán eliminados.',
+		),
+		'password_api' => 'Contraseña API <br /><small>(para apps móviles, por ej.)</small>',
+		'password_form' => 'Contraseña<br /><small>(para el método de identificación por formulario web)</small>',
+		'password_format' => 'Mínimo de 7 caracteres',
+		'title' => 'Perfil',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'Consultas de usuario',
 		'_' => 'Consultas de usuario',
 		'deprecated' => 'Esta consulta ya no es válida. La categoría referenciada o fuente ha sido eliminada.',
 		'deprecated' => 'Esta consulta ya no es válida. La categoría referenciada o fuente ha sido eliminada.',
-		'display' => 'Display user query results', // TODO
+		'display' => 'Display user query results',	//TODO - Translation
 		'filter' => 'Filtro aplicado:',
 		'filter' => 'Filtro aplicado:',
 		'get_all' => 'Mostrar todos los artículos',
 		'get_all' => 'Mostrar todos los artículos',
 		'get_category' => 'Mostrar la categoría "%s"',
 		'get_category' => 'Mostrar la categoría "%s"',
@@ -53,7 +64,7 @@ return array(
 		'number' => 'Consulta n° %d',
 		'number' => 'Consulta n° %d',
 		'order_asc' => 'Mostrar primero los artículos más antiguos',
 		'order_asc' => 'Mostrar primero los artículos más antiguos',
 		'order_desc' => 'Mostrar primero los artículos más recientes',
 		'order_desc' => 'Mostrar primero los artículos más recientes',
-		'remove' => 'Remove user query', // TODO
+		'remove' => 'Remove user query',	//TODO - Translation
 		'search' => 'Buscar "%s"',
 		'search' => 'Buscar "%s"',
 		'state_0' => 'Mostrar todos los artículos',
 		'state_0' => 'Mostrar todos los artículos',
 		'state_1' => 'Mostrar artículos leídos',
 		'state_1' => 'Mostrar artículos leídos',
@@ -73,31 +84,19 @@ return array(
 		'state_15' => 'Mostrar todos los artículos',
 		'state_15' => 'Mostrar todos los artículos',
 		'title' => 'Consultas de usuario',
 		'title' => 'Consultas de usuario',
 	),
 	),
-	'profile' => array(
-		'_' => 'Administración de perfiles',
-		'delete' => array(
-			'_' => 'Borrar cuenta',
-			'warn' => 'Tu cuenta y todos los datos asociados serán eliminados.',
-		),
-		'password_api' => 'Contraseña API <br /><small>(para apps móviles, por ej.)</small>',
-		'password_form' => 'Contraseña<br /><small>(para el método de identificación por formulario web)</small>',
-		'password_format' => 'Mínimo de 7 caracteres',
-		'title' => 'Perfil',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Lectura',
 		'_' => 'Lectura',
 		'after_onread' => 'Tras “marcar todo como leído”,',
 		'after_onread' => 'Tras “marcar todo como leído”,',
 		'articles_per_page' => 'Número de artículos por página',
 		'articles_per_page' => 'Número de artículos por página',
 		'auto_load_more' => 'Cargar más artículos al final de la página',
 		'auto_load_more' => 'Cargar más artículos al final de la página',
 		'auto_remove_article' => 'Ocultar artículos tras la lectura',
 		'auto_remove_article' => 'Ocultar artículos tras la lectura',
-		'mark_updated_article_unread' => 'Marcar artículos actualizados como no leídos',
 		'confirm_enabled' => 'Mostrar ventana de confirmación al usar la función “marcar todos como leídos”',
 		'confirm_enabled' => 'Mostrar ventana de confirmación al usar la función “marcar todos como leídos”',
 		'display_articles_unfolded' => 'Mostrar los artículos sin expandir por defecto',
 		'display_articles_unfolded' => 'Mostrar los artículos sin expandir por defecto',
 		'display_categories_unfolded' => 'Mostrar categorías expandidas por defecto',
 		'display_categories_unfolded' => 'Mostrar categorías expandidas por defecto',
 		'hide_read_feeds' => 'Ocultar categorías & fuentes sin artículos no leídos (no funciona con la configuración "Mostrar todos los artículos")',
 		'hide_read_feeds' => 'Ocultar categorías & fuentes sin artículos no leídos (no funciona con la configuración "Mostrar todos los artículos")',
 		'img_with_lazyload' => 'Usar el modo de "carga perezosa" para las imágenes',
 		'img_with_lazyload' => 'Usar el modo de "carga perezosa" para las imágenes',
-		'sides_close_article' => 'Pinchar fuera del área de texto del artículo lo cerrará',
 		'jump_next' => 'saltar al siguiente archivo sin leer emparentado (fuente o categoría)',
 		'jump_next' => 'saltar al siguiente archivo sin leer emparentado (fuente o categoría)',
+		'mark_updated_article_unread' => 'Marcar artículos actualizados como no leídos',
 		'number_divided_when_reader' => 'Dividido en 2 en la vista de lectura.',
 		'number_divided_when_reader' => 'Dividido en 2 en la vista de lectura.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'cuando el artículo se abra en su web original',
 			'article_open_on_website' => 'cuando el artículo se abra en su web original',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => 'Mostrar todos los artículos',
 			'all_articles' => 'Mostrar todos los artículos',
 			'unread' => 'Mostrar solo pendientes',
 			'unread' => 'Mostrar solo pendientes',
 		),
 		),
+		'sides_close_article' => 'Pinchar fuera del área de texto del artículo lo cerrará',
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Orden',
 			'_' => 'Orden',
 			'newer_first' => 'Nuevos primero',
 			'newer_first' => 'Nuevos primero',
@@ -128,7 +128,7 @@ return array(
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Compartir',
 		'_' => 'Compartir',
-		'add' => 'Add a sharing method', // TODO
+		'add' => 'Add a sharing method',	//TODO - Translation
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -136,7 +136,7 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'more_information' => 'Más información',
 		'more_information' => 'Más información',
 		'print' => 'Print',
 		'print' => 'Print',
-		'remove' => 'Remove sharing method', // TODO
+		'remove' => 'Remove sharing method',	//TODO - Translation
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
 		'share_name' => 'Compartir nombre a mostrar',
 		'share_name' => 'Compartir nombre a mostrar',
 		'share_url' => 'Compatir URL a usar',
 		'share_url' => 'Compatir URL a usar',
@@ -153,27 +153,30 @@ return array(
 		'collapse_article' => 'Contraer',
 		'collapse_article' => 'Contraer',
 		'first_article' => 'Saltar al primer artículo',
 		'first_article' => 'Saltar al primer artículo',
 		'focus_search' => 'Acceso a la casilla de búsqueda',
 		'focus_search' => 'Acceso a la casilla de búsqueda',
-		'global_view' => 'Switch to global view', // TODO
+		'global_view' => 'Switch to global view',	//TODO - Translation
 		'help' => 'Mostrar documentación',
 		'help' => 'Mostrar documentación',
 		'javascript' => 'JavaScript debe estar activado para poder usar atajos de teclado',
 		'javascript' => 'JavaScript debe estar activado para poder usar atajos de teclado',
 		'last_article' => 'Saltar al último artículo',
 		'last_article' => 'Saltar al último artículo',
 		'load_more' => 'Cargar más artículos',
 		'load_more' => 'Cargar más artículos',
-		'mark_read' => 'Marcar como leído',
 		'mark_favorite' => 'Marcar como favorito',
 		'mark_favorite' => 'Marcar como favorito',
+		'mark_read' => 'Marcar como leído',
 		'navigation' => 'Navegación',
 		'navigation' => 'Navegación',
 		'navigation_help' => 'Con el modificador "Mayúsculas" es posible usar los atajos de teclado en las fuentes.<br/>Con el modificador "Alt" es posible aplicar los atajos de teclado en las categorías.',
 		'navigation_help' => 'Con el modificador "Mayúsculas" es posible usar los atajos de teclado en las fuentes.<br/>Con el modificador "Alt" es posible aplicar los atajos de teclado en las categorías.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => 'Saltar al siguiente artículo',
 		'next_article' => 'Saltar al siguiente artículo',
-		'normal_view' => 'Switch to normal view', // TODO
+		'normal_view' => 'Switch to normal view',	//TODO - Translation
 		'other_action' => 'Otras acciones',
 		'other_action' => 'Otras acciones',
 		'previous_article' => 'Saltar al artículo anterior',
 		'previous_article' => 'Saltar al artículo anterior',
-		'reading_view' => 'Switch to reading view', // TODO
-		'rss_view' => 'Open RSS view in a new tab', // TODO
+		'reading_view' => 'Switch to reading view',	//TODO - Translation
+		'rss_view' => 'Open RSS view in a new tab',	//TODO - Translation
 		'see_on_website' => 'Ver en la web original',
 		'see_on_website' => 'Ver en la web original',
 		'shift_for_all_read' => '+ <code>mayúsculas</code> para marcar todos los artículos como leídos',
 		'shift_for_all_read' => '+ <code>mayúsculas</code> para marcar todos los artículos como leídos',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => 'Atajos de teclado',
 		'title' => 'Atajos de teclado',
 		'user_filter' => 'Acceso a filtros de usuario',
 		'user_filter' => 'Acceso a filtros de usuario',
 		'user_filter_help' => 'Si solo hay un filtro de usuario, ese será el que se use. En caso contrario, los filtros están accesibles por su númeración.',
 		'user_filter_help' => 'Si solo hay un filtro de usuario, ese será el que se use. En caso contrario, los filtros están accesibles por su númeración.',
-		'views' => 'Views', // TODO
+		'views' => 'Views',	//TODO - Translation
 	),
 	),
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s artículos (%s)',
 		'articles_and_size' => '%s artículos (%s)',

+ 9 - 9
app/i18n/es/feedback.php

@@ -50,11 +50,15 @@ return array(
 		'no_zip_extension' => 'La extensión ZIP no está disponible en tu servidor.',
 		'no_zip_extension' => 'La extensión ZIP no está disponible en tu servidor.',
 		'zip_error' => 'Hubo un error durante la importación ZIP.',
 		'zip_error' => 'Hubo un error durante la importación ZIP.',
 	),
 	),
+	'profile' => array(
+		'error' => 'Tu perfil no puede ser modificado',
+		'updated' => 'Tu perfil ha sido modificado',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Actualización',
 		'actualize' => 'Actualización',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	//TODO
-			'marked_unread' => 'The articles have been marked as unread.',	//TODO
+			'marked_read' => 'The selected articles have been marked as read.',	//TODO - Translation
+			'marked_unread' => 'The articles have been marked as unread.',	//TODO - Translation
 		),
 		),
 		'category' => array(
 		'category' => array(
 			'created' => 'Se ha creado la categoría %s.',
 			'created' => 'Se ha creado la categoría %s.',
@@ -76,7 +80,7 @@ return array(
 			'already_subscribed' => 'Ya estás suscrito a <em>%s</em>',
 			'already_subscribed' => 'Ya estás suscrito a <em>%s</em>',
 			'deleted' => 'Fuente eliminada',
 			'deleted' => 'Fuente eliminada',
 			'error' => 'No es posible actualizar la fuente',
 			'error' => 'No es posible actualizar la fuente',
-			'internal_problem' => 'No ha sido posible agregar la fuente RSS. <a href="%s">Revisa el registro de FreshRSS </a> para más información.', // @todo
+			'internal_problem' => 'No ha sido posible agregar la fuente RSS. <a href="%s">Revisa el registro de FreshRSS </a> para más información.',	//TODO - Translation
 			'invalid_url' => 'La URL <em>%s</em> es inválida',
 			'invalid_url' => 'La URL <em>%s</em> es inválida',
 			'n_actualized' => 'Se han actualiado %d fuentes',
 			'n_actualized' => 'Se han actualiado %d fuentes',
 			'n_entries_deleted' => 'Se han eliminado %d artículos',
 			'n_entries_deleted' => 'Se han eliminado %d artículos',
@@ -105,12 +109,8 @@ return array(
 			'error' => 'El usuario %s no ha podido ser eliminado',
 			'error' => 'El usuario %s no ha podido ser eliminado',
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated', // TODO
-			'error' => 'User %s has not been updated', // TODO
+			'_' => 'User %s has been updated',	//TODO - Translation
+			'error' => 'User %s has not been updated',	//TODO - Translation
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => 'Tu perfil no puede ser modificado',
-		'updated' => 'Tu perfil ha sido modificado',
-	),
 );
 );

+ 15 - 13
app/i18n/es/gen.php

@@ -19,7 +19,7 @@ return array(
 		'see_website' => 'Ver web',
 		'see_website' => 'Ver web',
 		'submit' => 'Enviar',
 		'submit' => 'Enviar',
 		'truncate' => 'Borrar todos los artículos',
 		'truncate' => 'Borrar todos los artículos',
-		'update' => 'Update', // TODO
+		'update' => 'Update',	//TODO - Translation
 	),
 	),
 	'auth' => array(
 	'auth' => array(
 		'email' => 'Correo electrónico',
 		'email' => 'Correo electrónico',
@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\A\\b\\r\\i\\l',
 		'Apr' => '\\A\\b\\r\\i\\l',
-		'Aug' => '\\A\\g\\o\\s\\t\\o',
-		'Dec' => '\\D\\i\\c\\i\\e\\m\\b\\r\\e',
-		'Feb' => '\\F\\e\\b\\r\\e\\r\\o',
-		'Jan' => '\\E\\n\\e\\r\\o',
-		'Jul' => '\\J\\u\\l\\i\\o',
-		'Jun' => '\\J\\u\\n\\i\\o',
-		'Mar' => '\\M\\a\\r\\z\\o',
-		'May' => '\\M\\a\\y\\o',
-		'Nov' => '\\N\\o\\v\\i\\e\\m\\b\\r\\e',
-		'Oct' => '\\O\\c\\t\\u\\b\\r\\e',
-		'Sep' => '\\S\\e\\p\\t\\i\\e\\m\\b\\r\\e',
 		'apr' => 'abr',
 		'apr' => 'abr',
 		'april' => 'abril',
 		'april' => 'abril',
+		'Aug' => '\\A\\g\\o\\s\\t\\o',
 		'aug' => 'ago',
 		'aug' => 'ago',
 		'august' => 'agosto',
 		'august' => 'agosto',
 		'before_yesterday' => 'Anteayer',
 		'before_yesterday' => 'Anteayer',
+		'Dec' => '\\D\\i\\c\\i\\e\\m\\b\\r\\e',
 		'dec' => 'dic',
 		'dec' => 'dic',
 		'december' => 'diciembre',
 		'december' => 'diciembre',
+		'Feb' => '\\F\\e\\b\\r\\e\\r\\o',
 		'feb' => 'feb',
 		'feb' => 'feb',
 		'february' => 'febrero',
 		'february' => 'febrero',
 		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
 		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
 		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',
 		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',
 		'fri' => 'Vie',
 		'fri' => 'Vie',
+		'Jan' => '\\E\\n\\e\\r\\o',
 		'jan' => 'ene',
 		'jan' => 'ene',
 		'january' => 'ene',
 		'january' => 'ene',
+		'Jul' => '\\J\\u\\l\\i\\o',
 		'jul' => 'jul',
 		'jul' => 'jul',
 		'july' => 'julio',
 		'july' => 'julio',
+		'Jun' => '\\J\\u\\n\\i\\o',
 		'jun' => 'jun',
 		'jun' => 'jun',
 		'june' => 'junio',
 		'june' => 'junio',
 		'last_3_month' => 'Últimos tres meses',
 		'last_3_month' => 'Últimos tres meses',
@@ -78,17 +73,22 @@ return array(
 		'last_month' => 'Mes pasado',
 		'last_month' => 'Mes pasado',
 		'last_week' => 'Semana pasada',
 		'last_week' => 'Semana pasada',
 		'last_year' => 'Año pasado',
 		'last_year' => 'Año pasado',
+		'Mar' => '\\M\\a\\r\\z\\o',
 		'mar' => 'mar',
 		'mar' => 'mar',
 		'march' => 'marzo',
 		'march' => 'marzo',
+		'May' => '\\M\\a\\y\\o',
 		'may' => 'mayo',
 		'may' => 'mayo',
 		'may_' => 'may',
 		'may_' => 'may',
 		'mon' => 'Lun',
 		'mon' => 'Lun',
 		'month' => 'meses',
 		'month' => 'meses',
+		'Nov' => '\\N\\o\\v\\i\\e\\m\\b\\r\\e',
 		'nov' => 'nov',
 		'nov' => 'nov',
 		'november' => 'noviembre',
 		'november' => 'noviembre',
+		'Oct' => '\\O\\c\\t\\u\\b\\r\\e',
 		'oct' => 'oct',
 		'oct' => 'oct',
 		'october' => 'octubre',
 		'october' => 'octubre',
 		'sat' => 'Sab',
 		'sat' => 'Sab',
+		'Sep' => '\\S\\e\\p\\t\\i\\e\\m\\b\\r\\e',
 		'sep' => 'sep',
 		'sep' => 'sep',
 		'september' => 'septiembre',
 		'september' => 'septiembre',
 		'sun' => 'Dom',
 		'sun' => 'Dom',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -160,7 +161,6 @@ return array(
 		'previous' => 'Anterior',
 		'previous' => 'Anterior',
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -168,9 +168,11 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'gnusocial' => 'GNU social',
 		'gnusocial' => 'GNU social',
 		'jdh' => 'Journal du hacker',
 		'jdh' => 'Journal du hacker',
+		'Known' => 'Known based sites',
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Print',
 		'print' => 'Print',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',

+ 3 - 3
app/i18n/es/index.php

@@ -40,7 +40,7 @@ return array(
 		'mark_all_read' => 'Marcar todo como leído',
 		'mark_all_read' => 'Marcar todo como leído',
 		'mark_cat_read' => 'Marcar categoría como leída',
 		'mark_cat_read' => 'Marcar categoría como leída',
 		'mark_feed_read' => 'Marcar fuente como leída',
 		'mark_feed_read' => 'Marcar fuente como leída',
-		'mark_selection_unread' => 'Mark selection as unread',	//TODO
+		'mark_selection_unread' => 'Mark selection as unread',	//TODO - Translation
 		'newer_first' => 'Nuevos primero',
 		'newer_first' => 'Nuevos primero',
 		'non-starred' => 'Mostrar todos menos los favoritos',
 		'non-starred' => 'Mostrar todos menos los favoritos',
 		'normal_view' => 'Vista normal',
 		'normal_view' => 'Vista normal',
@@ -53,11 +53,11 @@ return array(
 		'starred' => 'Mostrar solo los favoritos',
 		'starred' => 'Mostrar solo los favoritos',
 		'stats' => 'Estadísticas',
 		'stats' => 'Estadísticas',
 		'subscription' => 'Administración de suscripciones',
 		'subscription' => 'Administración de suscripciones',
-		'tags' => 'My labels',	//TODO
+		'tags' => 'My labels',	//TODO - Translation
 		'unread' => 'Mostar solo no leídos',
 		'unread' => 'Mostar solo no leídos',
 	),
 	),
 	'share' => 'Compartir',
 	'share' => 'Compartir',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Etiquetas relacionadas',	//TODO
+		'related' => 'Etiquetas relacionadas',	//TODO - Translation
 	),
 	),
 );
 );

+ 3 - 3
app/i18n/es/install.php

@@ -24,8 +24,8 @@ return array(
 			'ok' => 'La configuración de la base de datos ha sido guardada.',
 			'ok' => 'La configuración de la base de datos ha sido guardada.',
 		),
 		),
 		'host' => 'Servidor',
 		'host' => 'Servidor',
-		'prefix' => 'Prefijo de la tabla',
 		'password' => 'Contraseña de la base de datos',
 		'password' => 'Contraseña de la base de datos',
+		'prefix' => 'Prefijo de la tabla',
 		'type' => 'Tipo de base de datos',
 		'type' => 'Tipo de base de datos',
 		'username' => 'Nombre de usuario de la base de datos',
 		'username' => 'Nombre de usuario de la base de datos',
 	),
 	),
@@ -69,8 +69,8 @@ return array(
 			'ok' => 'Dispones de la librería recomendada para procesar JSON.',
 			'ok' => 'Dispones de la librería recomendada para procesar JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'No se ha podido localizar el entorno Minz.',
 			'nok' => 'No se ha podido localizar el entorno Minz.',

+ 28 - 10
app/i18n/es/sub.php

@@ -2,8 +2,13 @@
 
 
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',// TODO
-		'title' => 'API',// TODO
+		'documentation' => 'Copy the following URL to use it within an external tool.',	//TODO - Translation
+		'title' => 'API',	//TODO - Translation
+	),
+	'bookmarklet' => array(
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',	//TODO - Translation
+		'label' => 'Subscribe',	//TODO - Translation
+		'title' => 'Bookmarklet',	//TODO - Translation
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Categoría',
 		'_' => 'Categoría',
@@ -22,7 +27,7 @@ return array(
 			'password' => 'Contraseña HTTP',
 			'password' => 'Contraseña HTTP',
 			'username' => 'Nombre de usuario HTTP',
 			'username' => 'Nombre de usuario HTTP',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	//TODO
+		'clear_cache' => 'Always clear cache',	//TODO - Translation
 		'css_help' => 'Recibir fuentes RSS truncadas (aviso, ¡necesita más tiempo!)',
 		'css_help' => 'Recibir fuentes RSS truncadas (aviso, ¡necesita más tiempo!)',
 		'css_path' => 'Ruta a la CSS de los artículos en la web original',
 		'css_path' => 'Ruta a la CSS de los artículos en la web original',
 		'description' => 'Descripción',
 		'description' => 'Descripción',
@@ -31,26 +36,37 @@ return array(
 		'informations' => 'Información',
 		'informations' => 'Información',
 		'keep_history' => 'Número mínimo de artículos a conservar',
 		'keep_history' => 'Número mínimo de artículos a conservar',
 		'moved_category_deleted' => 'Al borrar una categoría todas sus fuentes pasan automáticamente a la categoría <em>%s</em>.',
 		'moved_category_deleted' => 'Al borrar una categoría todas sus fuentes pasan automáticamente a la categoría <em>%s</em>.',
-		'mute' => 'mute', // TODO
+		'mute' => 'mute',	//TODO - Translation
 		'no_selected' => 'No hay funentes seleccionadas.',
 		'no_selected' => 'No hay funentes seleccionadas.',
 		'number_entries' => '%d artículos',
 		'number_entries' => '%d artículos',
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility', // TODO
-			'archived' => 'Do not show (archived)', // TODO
+			'_' => 'Visibility',	//TODO - Translation
+			'archived' => 'Do not show (archived)',	//TODO - Translation
 			'main_stream' => 'Mostrar en salida principal',
 			'main_stream' => 'Mostrar en salida principal',
-			'normal' => 'Show in its category', // TODO
+			'normal' => 'Show in its category',	//TODO - Translation
+		),
+		'websub' => 'Notificación inmedaiata con WebSub',
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	//TODO
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
+		'ssl_verify' => 'Verify SSL security',	//TODO - Translation
 		'stats' => 'Estadísticas',
 		'stats' => 'Estadísticas',
 		'think_to_add' => 'Puedes añadir fuentes.',
 		'think_to_add' => 'Puedes añadir fuentes.',
-		'timeout' => 'Timeout in seconds',	//TODO
+		'timeout' => 'Timeout in seconds',	//TODO - Translation
 		'title' => 'Título',
 		'title' => 'Título',
 		'title_add' => 'Añadir fuente RSS',
 		'title_add' => 'Añadir fuente RSS',
 		'ttl' => 'No actualizar de forma automática con una frecuencia mayor a',
 		'ttl' => 'No actualizar de forma automática con una frecuencia mayor a',
 		'url' => 'URL de la fuente',
 		'url' => 'URL de la fuente',
 		'validator' => 'Verifica la validez de la fuente',
 		'validator' => 'Verifica la validez de la fuente',
 		'website' => 'Web de la URL',
 		'website' => 'Web de la URL',
-		'pubsubhubbub' => 'Notificación inmedaiata con PubSubHubbub',
+	),
+	'firefox' => array(
+		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',	//TODO - Translation
+		'title' => 'Firefox feed reader',	//TODO - Translation
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export' => 'Exportar',
 		'export' => 'Exportar',
@@ -67,9 +83,11 @@ return array(
 		'bookmark' => 'Suscribirse (favorito FreshRSS)',
 		'bookmark' => 'Suscribirse (favorito FreshRSS)',
 		'import_export' => 'Importar / exportar',
 		'import_export' => 'Importar / exportar',
 		'subscription_management' => 'Administración de suscripciones',
 		'subscription_management' => 'Administración de suscripciones',
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 	'title' => array(
 	'title' => array(
 		'_' => 'Administración de suscripciones',
 		'_' => 'Administración de suscripciones',
 		'feed_management' => 'Administración de fuentes RSS',
 		'feed_management' => 'Administración de fuentes RSS',
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 );
 );

+ 10 - 6
app/i18n/fr/admin.php

@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Auteur',
+		'community' => 'Extensions utilisateur disponibles',
+		'description' => 'Description',
 		'disabled' => 'Désactivée',
 		'disabled' => 'Désactivée',
 		'empty_list' => 'Aucune extension installée',
 		'empty_list' => 'Aucune extension installée',
 		'enabled' => 'Activée',
 		'enabled' => 'Activée',
+		'latest' => 'Installée',
+		'name' => 'Nom',
 		'no_configure_view' => 'Cette extension n’a pas à être configurée',
 		'no_configure_view' => 'Cette extension n’a pas à être configurée',
 		'system' => array(
 		'system' => array(
 			'_' => 'Extensions système',
 			'_' => 'Extensions système',
 			'no_rights' => 'Extensions système (contrôlées par l’administrateur)',
 			'no_rights' => 'Extensions système (contrôlées par l’administrateur)',
 		),
 		),
 		'title' => 'Extensions',
 		'title' => 'Extensions',
+		'update' => 'Mise à jour disponible',
 		'user' => 'Extensions utilisateur',
 		'user' => 'Extensions utilisateur',
-		'community' => 'Extensions utilisateur disponibles',
-		'name' => 'Nom',
 		'version' => 'Version',
 		'version' => 'Version',
-		'description' => 'Description',
-		'author' => 'Auteur',
-		'latest' => 'Installée',
-		'update' => 'Mise à jour disponible',
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistiques',
 		'_' => 'Statistiques',
@@ -162,6 +162,10 @@ return array(
 		'instance-name' => 'Nom de l’instance',
 		'instance-name' => 'Nom de l’instance',
 		'max-categories' => 'Limite de catégories par utilisateur',
 		'max-categories' => 'Limite de catégories par utilisateur',
 		'max-feeds' => 'Limite de flux par utilisateur',
 		'max-feeds' => 'Limite de flux par utilisateur',
+		'cookie-duration' => array(
+			'help' => 'en secondes',
+			'number' => 'Durée avant expiration de la session',
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => 'Un chiffre de 0 signifie que l’on peut créer un nombre infini de comptes',
 			'help' => 'Un chiffre de 0 signifie que l’on peut créer un nombre infini de comptes',
 			'number' => 'Nombre max de comptes',
 			'number' => 'Nombre max de comptes',

+ 18 - 15
app/i18n/fr/conf.php

@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'secondes (0 signifie aucun timeout)',
 			'seconds' => 'secondes (0 signifie aucun timeout)',
 			'timeout' => 'Temps d’affichage de la notification HTML5',
 			'timeout' => 'Temps d’affichage de la notification HTML5',
 		),
 		),
+		'show_nav_buttons' => 'Afficher les boutons de navigation',
 		'theme' => 'Thème',
 		'theme' => 'Thème',
 		'title' => 'Affichage',
 		'title' => 'Affichage',
 		'width' => array(
 		'width' => array(
@@ -37,7 +38,17 @@ return array(
 			'no_limit' => 'Pas de limite',
 			'no_limit' => 'Pas de limite',
 			'thin' => 'Fine',
 			'thin' => 'Fine',
 		),
 		),
-		'show_nav_buttons' => 'Afficher les boutons de navigation',
+	),
+	'profile' => array(
+		'_' => 'Gestion du profil',
+		'delete' => array(
+			'_' => 'Suppression du compte',
+			'warn' => 'Le compte et toutes les données associées vont être supprimées.',
+		),
+		'password_api' => 'Mot de passe API<br /><small>(ex. : pour applis mobiles)</small>',
+		'password_form' => 'Mot de passe<br /><small>(pour connexion par formulaire)</small>',
+		'password_format' => '7 caractères minimum',
+		'title' => 'Profil',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'Filtres utilisateurs',
 		'_' => 'Filtres utilisateurs',
@@ -73,31 +84,19 @@ return array(
 		'state_15' => 'Afficher tous les articles',
 		'state_15' => 'Afficher tous les articles',
 		'title' => 'Filtres utilisateurs',
 		'title' => 'Filtres utilisateurs',
 	),
 	),
-	'profile' => array(
-		'_' => 'Gestion du profil',
-		'delete' => array(
-			'_' => 'Suppression du compte',
-			'warn' => 'Le compte et toutes les données associées vont être supprimées.',
-		),
-		'password_api' => 'Mot de passe API<br /><small>(ex. : pour applis mobiles)</small>',
-		'password_form' => 'Mot de passe<br /><small>(pour connexion par formulaire)</small>',
-		'password_format' => '7 caractères minimum',
-		'title' => 'Profil',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Lecture',
 		'_' => 'Lecture',
 		'after_onread' => 'Après “marquer tout comme lu”,',
 		'after_onread' => 'Après “marquer tout comme lu”,',
 		'articles_per_page' => 'Nombre d’articles par page',
 		'articles_per_page' => 'Nombre d’articles par page',
 		'auto_load_more' => 'Charger les articles suivants en bas de page',
 		'auto_load_more' => 'Charger les articles suivants en bas de page',
 		'auto_remove_article' => 'Cacher les articles après lecture',
 		'auto_remove_article' => 'Cacher les articles après lecture',
-		'mark_updated_article_unread' => 'Marquer les articles mis à jour comme non-lus',
 		'confirm_enabled' => 'Afficher une confirmation lors des actions “marquer tout comme lu”',
 		'confirm_enabled' => 'Afficher une confirmation lors des actions “marquer tout comme lu”',
 		'display_articles_unfolded' => 'Afficher les articles dépliés par défaut',
 		'display_articles_unfolded' => 'Afficher les articles dépliés par défaut',
 		'display_categories_unfolded' => 'Afficher les catégories pliées par défaut',
 		'display_categories_unfolded' => 'Afficher les catégories pliées par défaut',
 		'hide_read_feeds' => 'Cacher les catégories & flux sans article non-lu (ne fonctionne pas avec la configuration “Afficher tous les articles”)',
 		'hide_read_feeds' => 'Cacher les catégories & flux sans article non-lu (ne fonctionne pas avec la configuration “Afficher tous les articles”)',
 		'img_with_lazyload' => 'Utiliser le mode “chargement différé” pour les images',
 		'img_with_lazyload' => 'Utiliser le mode “chargement différé” pour les images',
-		'sides_close_article' => 'Cliquer hors de la zone de texte ferme l’article',
 		'jump_next' => 'sauter au prochain voisin non lu (flux ou catégorie)',
 		'jump_next' => 'sauter au prochain voisin non lu (flux ou catégorie)',
+		'mark_updated_article_unread' => 'Marquer les articles mis à jour comme non-lus',
 		'number_divided_when_reader' => 'Divisé par 2 dans la vue de lecture.',
 		'number_divided_when_reader' => 'Divisé par 2 dans la vue de lecture.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'lorsque l’article est ouvert sur le site d’origine',
 			'article_open_on_website' => 'lorsque l’article est ouvert sur le site d’origine',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => 'Afficher tous les articles',
 			'all_articles' => 'Afficher tous les articles',
 			'unread' => 'Afficher les non lus',
 			'unread' => 'Afficher les non lus',
 		),
 		),
+		'sides_close_article' => 'Cliquer hors de la zone de texte ferme l’article',
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Ordre de tri',
 			'_' => 'Ordre de tri',
 			'newer_first' => 'Plus récents en premier',
 			'newer_first' => 'Plus récents en premier',
@@ -158,10 +158,11 @@ return array(
 		'javascript' => 'Le JavaScript doit être activé pour pouvoir profiter des raccourcis.',
 		'javascript' => 'Le JavaScript doit être activé pour pouvoir profiter des raccourcis.',
 		'last_article' => 'Passer au dernier article',
 		'last_article' => 'Passer au dernier article',
 		'load_more' => 'Charger plus d’articles',
 		'load_more' => 'Charger plus d’articles',
-		'mark_read' => 'Marquer comme lu',
 		'mark_favorite' => 'Mettre en favori',
 		'mark_favorite' => 'Mettre en favori',
+		'mark_read' => 'Marquer comme lu',
 		'navigation' => 'Navigation',
 		'navigation' => 'Navigation',
 		'navigation_help' => 'Avec le modificateur "Shift", les raccourcis de navigation s’appliquent aux flux.<br/>Avec le modificateur "Alt", les raccourcis de navigation s’appliquent aux catégories.',
 		'navigation_help' => 'Avec le modificateur "Shift", les raccourcis de navigation s’appliquent aux flux.<br/>Avec le modificateur "Alt", les raccourcis de navigation s’appliquent aux catégories.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => 'Passer à l’article suivant',
 		'next_article' => 'Passer à l’article suivant',
 		'normal_view' => 'Basculer vers la vue normale',
 		'normal_view' => 'Basculer vers la vue normale',
 		'other_action' => 'Autres actions',
 		'other_action' => 'Autres actions',
@@ -170,6 +171,8 @@ return array(
 		'rss_view' => 'Ouvrir le flux RSS dans un nouvel onglet',
 		'rss_view' => 'Ouvrir le flux RSS dans un nouvel onglet',
 		'see_on_website' => 'Voir sur le site d’origine',
 		'see_on_website' => 'Voir sur le site d’origine',
 		'shift_for_all_read' => '+ <code>shift</code> pour marquer tous les articles comme lus',
 		'shift_for_all_read' => '+ <code>shift</code> pour marquer tous les articles comme lus',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => 'Raccourcis',
 		'title' => 'Raccourcis',
 		'user_filter' => 'Accéder aux filtres utilisateur',
 		'user_filter' => 'Accéder aux filtres utilisateur',
 		'user_filter_help' => 'S’il n’y a qu’un filtre utilisateur, celui-ci est utilisé automatiquement. Sinon ils sont accessibles par leur numéro.',
 		'user_filter_help' => 'S’il n’y a qu’un filtre utilisateur, celui-ci est utilisé automatiquement. Sinon ils sont accessibles par leur numéro.',

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

@@ -50,6 +50,10 @@ return array(
 		'no_zip_extension' => 'L’extension ZIP n’est pas présente sur votre serveur.',
 		'no_zip_extension' => 'L’extension ZIP n’est pas présente sur votre serveur.',
 		'zip_error' => 'Une erreur est survenue durant l’import du fichier ZIP.',
 		'zip_error' => 'Une erreur est survenue durant l’import du fichier ZIP.',
 	),
 	),
+	'profile' => array(
+		'error' => 'Votre profil n’a pas pu être mis à jour',
+		'updated' => 'Votre profil a été mis à jour',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Actualiser',
 		'actualize' => 'Actualiser',
 		'articles' => array(
 		'articles' => array(
@@ -109,8 +113,4 @@ return array(
 			'error' => 'L’utilisateur %s n’a pas été mis à jour',
 			'error' => 'L’utilisateur %s n’a pas été mis à jour',
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => 'Votre profil n’a pas pu être mis à jour',
-		'updated' => 'Votre profil a été mis à jour',
-	),
 );
 );

+ 14 - 12
app/i18n/fr/gen.php

@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\a\\v\\r\\i\\l',
 		'Apr' => '\\a\\v\\r\\i\\l',
-		'Aug' => '\\a\\o\\û\\t',
-		'Dec' => '\\d\\é\\c\\e\\m\\b\\r\\e',
-		'Feb' => '\\f\\é\\v\\r\\i\\e\\r',
-		'Jan' => '\\j\\a\\n\\v\\i\\e\\r',
-		'Jul' => '\\j\\u\\i\\l\\l\\e\\t',
-		'Jun' => '\\j\\u\\i\\n',
-		'Mar' => '\\m\\a\\r\\s',
-		'May' => '\\m\\a\\i',
-		'Nov' => '\\n\\o\\v\\e\\m\\b\\r\\e',
-		'Oct' => '\\o\\c\\t\\o\\b\\r\\e',
-		'Sep' => '\\s\\e\\p\\t\\e\\m\\b\\r\\e',
 		'apr' => 'avr.',
 		'apr' => 'avr.',
 		'april' => 'avril',
 		'april' => 'avril',
+		'Aug' => '\\a\\o\\û\\t',
 		'aug' => 'août',
 		'aug' => 'août',
 		'august' => 'août',
 		'august' => 'août',
 		'before_yesterday' => 'À partir d’avant-hier',
 		'before_yesterday' => 'À partir d’avant-hier',
+		'Dec' => '\\d\\é\\c\\e\\m\\b\\r\\e',
 		'dec' => 'déc.',
 		'dec' => 'déc.',
 		'december' => 'décembre',
 		'december' => 'décembre',
+		'Feb' => '\\f\\é\\v\\r\\i\\e\\r',
 		'feb' => 'fév.',
 		'feb' => 'fév.',
 		'february' => 'février',
 		'february' => 'février',
 		'format_date' => 'j %s Y',
 		'format_date' => 'j %s Y',
 		'format_date_hour' => 'j %s Y \\à H\\:i',
 		'format_date_hour' => 'j %s Y \\à H\\:i',
 		'fri' => 'ven.',
 		'fri' => 'ven.',
+		'Jan' => '\\j\\a\\n\\v\\i\\e\\r',
 		'jan' => 'jan.',
 		'jan' => 'jan.',
 		'january' => 'janvier',
 		'january' => 'janvier',
+		'Jul' => '\\j\\u\\i\\l\\l\\e\\t',
 		'jul' => 'jui.',
 		'jul' => 'jui.',
 		'july' => 'juillet',
 		'july' => 'juillet',
+		'Jun' => '\\j\\u\\i\\n',
 		'jun' => 'juin',
 		'jun' => 'juin',
 		'june' => 'juin',
 		'june' => 'juin',
 		'last_3_month' => 'Depuis les trois derniers mois',
 		'last_3_month' => 'Depuis les trois derniers mois',
@@ -78,17 +73,22 @@ return array(
 		'last_month' => 'Depuis le mois dernier',
 		'last_month' => 'Depuis le mois dernier',
 		'last_week' => 'Depuis la semaine dernière',
 		'last_week' => 'Depuis la semaine dernière',
 		'last_year' => 'Depuis l’année dernière',
 		'last_year' => 'Depuis l’année dernière',
+		'Mar' => '\\m\\a\\r\\s',
 		'mar' => 'mars',
 		'mar' => 'mars',
 		'march' => 'mars',
 		'march' => 'mars',
+		'May' => '\\m\\a\\i',
 		'may' => 'mai',
 		'may' => 'mai',
 		'may_' => 'mai',
 		'may_' => 'mai',
 		'mon' => 'lun.',
 		'mon' => 'lun.',
 		'month' => 'mois',
 		'month' => 'mois',
+		'Nov' => '\\n\\o\\v\\e\\m\\b\\r\\e',
 		'nov' => 'nov.',
 		'nov' => 'nov.',
 		'november' => 'novembre',
 		'november' => 'novembre',
+		'Oct' => '\\o\\c\\t\\o\\b\\r\\e',
 		'oct' => 'oct.',
 		'oct' => 'oct.',
 		'october' => 'octobre',
 		'october' => 'octobre',
 		'sat' => 'sam.',
 		'sat' => 'sam.',
+		'Sep' => '\\s\\e\\p\\t\\e\\m\\b\\r\\e',
 		'sep' => 'sep.',
 		'sep' => 'sep.',
 		'september' => 'septembre',
 		'september' => 'septembre',
 		'sun' => 'dim.',
 		'sun' => 'dim.',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -160,7 +161,6 @@ return array(
 		'previous' => 'Précédent',
 		'previous' => 'Précédent',
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Sites basés sur Known',
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Courriel',
 		'email' => 'Courriel',
@@ -168,9 +168,11 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'gnusocial' => 'GNU social',
 		'gnusocial' => 'GNU social',
 		'jdh' => 'Journal du hacker',
 		'jdh' => 'Journal du hacker',
+		'Known' => 'Sites basés sur Known',
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Imprimer',
 		'print' => 'Imprimer',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',

+ 8 - 1
app/i18n/fr/sub.php

@@ -45,6 +45,14 @@ return array(
 			'main_stream' => 'Afficher dans le flux principal',
 			'main_stream' => 'Afficher dans le flux principal',
 			'normal' => 'Afficher dans sa catégorie',
 			'normal' => 'Afficher dans sa catégorie',
 		),
 		),
+		'websub' => 'Notification instantanée par WebSub',
+		'show' => array(
+			'all' => 'Montrer tous les flux',
+			'error' => 'Montrer seulement les flux en erreur',
+		),
+		'showing' => array(
+			'error' => 'Montre seulement les flux en erreur',
+		),
 		'ssl_verify' => 'Vérification sécurité SSL',
 		'ssl_verify' => 'Vérification sécurité SSL',
 		'stats' => 'Statistiques',
 		'stats' => 'Statistiques',
 		'think_to_add' => 'Vous pouvez ajouter des flux.',
 		'think_to_add' => 'Vous pouvez ajouter des flux.',
@@ -55,7 +63,6 @@ return array(
 		'url' => 'URL du flux',
 		'url' => 'URL du flux',
 		'validator' => 'Vérifier la validité du flux',
 		'validator' => 'Vérifier la validité du flux',
 		'website' => 'URL du site',
 		'website' => 'URL du site',
-		'pubsubhubbub' => 'Notification instantanée par PubSubHubbub',
 	),
 	),
 	'firefox' => array(
 	'firefox' => array(
 		'documentation' => 'Suivre les étapes décrites <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">ici</a> pour ajouter FreshRSS à la liste des lecteurs de flux dans Firefox.',
 		'documentation' => 'Suivre les étapes décrites <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">ici</a> pour ajouter FreshRSS à la liste des lecteurs de flux dans Firefox.',

+ 70 - 66
app/i18n/he/admin.php

@@ -8,10 +8,10 @@ return array(
 		'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)',
 		'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)',
 		'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)',
 		'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)',
 		'none' => 'ללא (מסוכן)',
 		'none' => 'ללא (מסוכן)',
-		'title' => 'Authentication', // @todo
+		'title' => 'Authentication',	//TODO - Translation
 		'title_reset' => 'איפוס אימות',
 		'title_reset' => 'איפוס אימות',
 		'token' => 'מחרוזת אימות',
 		'token' => 'מחרוזת אימות',
-		'token_help' => 'Allows to access RSS output of the default user without authentication:', // @todo
+		'token_help' => 'Allows to access RSS output of the default user without authentication:',	//TODO - Translation
 		'type' => 'שיטת אימות',
 		'type' => 'שיטת אימות',
 		'unsafe_autologin' => 'הרשאה להתחברות אוטומטית בפורמט: ',
 		'unsafe_autologin' => 'הרשאה להתחברות אוטומטית בפורמט: ',
 	),
 	),
@@ -21,12 +21,12 @@ return array(
 			'ok' => 'ההרשאות בתיקיית המטמון תקינות',
 			'ok' => 'ההרשאות בתיקיית המטמון תקינות',
 		),
 		),
 		'categories' => array(
 		'categories' => array(
-			'nok' => 'Category table is bad configured.', // @todo
-			'ok' => 'Category table is ok.', // @todo
+			'nok' => 'Category table is bad configured.',	//TODO - Translation
+			'ok' => 'Category table is ok.',	//TODO - Translation
 		),
 		),
 		'connection' => array(
 		'connection' => array(
-			'nok' => 'Connection to the database cannot being established.', // @todo
-			'ok' => 'Connection to the database is ok.', // @todo
+			'nok' => 'Connection to the database cannot being established.',	//TODO - Translation
+			'ok' => 'Connection to the database is ok.',	//TODO - Translation
 		),
 		),
 		'ctype' => array(
 		'ctype' => array(
 			'nok' => 'הספרייה הנדרשת ל character type checking (php-ctype) אינה מותקנת',
 			'nok' => 'הספרייה הנדרשת ל character type checking (php-ctype) אינה מותקנת',
@@ -34,44 +34,44 @@ return array(
 		),
 		),
 		'curl' => array(
 		'curl' => array(
 			'nok' => 'בURL לא מותקן (php-curl package)',
 			'nok' => 'בURL לא מותקן (php-curl package)',
-			'ok' => 'You have cURL extension.', // @todo
+			'ok' => 'You have cURL extension.',	//TODO - Translation
 		),
 		),
 		'data' => array(
 		'data' => array(
 			'nok' => 'יש לבדוק את ההרשאות בתיקייה <em>%s</em>. שרת הHTTP חייב להיות בעל הרשאות כתיבה.',
 			'nok' => 'יש לבדוק את ההרשאות בתיקייה <em>%s</em>. שרת הHTTP חייב להיות בעל הרשאות כתיבה.',
 			'ok' => 'ההרשאות בתיקיית הדאטא תקינות',
 			'ok' => 'ההרשאות בתיקיית הדאטא תקינות',
 		),
 		),
-		'database' => 'Database installation', // @todo
+		'database' => 'Database installation',	//TODO - Translation
 		'dom' => array(
 		'dom' => array(
 			'nok' => 'הספרייה הנדרשת לסיור ב DOM אינה מותקנת  (php-xml package)',
 			'nok' => 'הספרייה הנדרשת לסיור ב DOM אינה מותקנת  (php-xml package)',
 			'ok' => 'הספרייה הנדרשת לסיור ב DOM מותקנת',
 			'ok' => 'הספרייה הנדרשת לסיור ב DOM מותקנת',
 		),
 		),
 		'entries' => array(
 		'entries' => array(
-			'nok' => 'Entry table is bad configured.', // @todo
-			'ok' => 'Entry table is ok.', // @todo
+			'nok' => 'Entry table is bad configured.',	//TODO - Translation
+			'ok' => 'Entry table is ok.',	//TODO - Translation
 		),
 		),
 		'favicons' => array(
 		'favicons' => array(
-			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have rights to write into', // @todo
+			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have rights to write into',	//TODO - Translation
 			'ok' => 'ההרשאות בתיקיית הfavicons תקינות',
 			'ok' => 'ההרשאות בתיקיית הfavicons תקינות',
 		),
 		),
 		'feeds' => array(
 		'feeds' => array(
-			'nok' => 'Feed table is bad configured.', // @todo
-			'ok' => 'Feed table is ok.', // @todo
+			'nok' => 'Feed table is bad configured.',	//TODO - Translation
+			'ok' => 'Feed table is ok.',	//TODO - Translation
 		),
 		),
 		'fileinfo' => array(
 		'fileinfo' => array(
-			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).', // @todo
-			'ok' => 'You have the fileinfo library.', // @todo
+			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	//TODO - Translation
+			'ok' => 'You have the fileinfo library.',	//TODO - Translation
 		),
 		),
-		'files' => 'File installation', // @todo
+		'files' => 'File installation',	//TODO - Translation
 		'json' => array(
 		'json' => array(
-			'nok' => 'You lack JSON (php-json package).', // @todo
-			'ok' => 'You have JSON extension.', // @todo
+			'nok' => 'You lack JSON (php-json package).',	//TODO - Translation
+			'ok' => 'You have JSON extension.',	//TODO - Translation
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
-			'nok' => 'You lack the Minz framework.', // @todo
+			'nok' => 'You lack the Minz framework.',	//TODO - Translation
 			'ok' => 'יש לכם את תשתית Minz',
 			'ok' => 'יש לכם את תשתית Minz',
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
@@ -83,46 +83,46 @@ return array(
 			'ok' => 'PDO מותקן ולפחות אחד ממנהלי ההתקן הנתמכים מותקן (pdo_mysql, pdo_sqlite)',
 			'ok' => 'PDO מותקן ולפחות אחד ממנהלי ההתקן הנתמכים מותקן (pdo_mysql, pdo_sqlite)',
 		),
 		),
 		'php' => array(
 		'php' => array(
-			'_' => 'PHP installation', // @todo
+			'_' => 'PHP installation',	//TODO - Translation
 			'nok' => 'גירסת PHP שלכם היא %s אך FreshRSS דורש לפחות את גירסה %s',
 			'nok' => 'גירסת PHP שלכם היא %s אך FreshRSS דורש לפחות את גירסה %s',
 			'ok' => 'גירסת PHP שלכם היא %s, שתואמת ל FreshRSS',
 			'ok' => 'גירסת PHP שלכם היא %s, שתואמת ל FreshRSS',
 		),
 		),
 		'tables' => array(
 		'tables' => array(
-			'nok' => 'There is one or more lacking tables in the database.', // @todo
-			'ok' => 'Tables are existing in the database.', // @todo
+			'nok' => 'There is one or more lacking tables in the database.',	//TODO - Translation
+			'ok' => 'Tables are existing in the database.',	//TODO - Translation
 		),
 		),
-		'title' => 'Installation checking', // @todo
+		'title' => 'Installation checking',	//TODO - Translation
 		'tokens' => array(
 		'tokens' => array(
-			'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have rights to write into', // @todo
-			'ok' => 'Permissions on tokens directory are good.', // @todo
+			'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have rights to write into',	//TODO - Translation
+			'ok' => 'Permissions on tokens directory are good.',	//TODO - Translation
 		),
 		),
 		'users' => array(
 		'users' => array(
-			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have rights to write into', // @todo
-			'ok' => 'Permissions on users directory are good.', // @todo
+			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have rights to write into',	//TODO - Translation
+			'ok' => 'Permissions on users directory are good.',	//TODO - Translation
 		),
 		),
 		'zip' => array(
 		'zip' => array(
-			'nok' => 'You lack ZIP extension (php-zip package).', // @todo
-			'ok' => 'You have ZIP extension.', // @todo
+			'nok' => 'You lack ZIP extension (php-zip package).',	//TODO - Translation
+			'ok' => 'You have ZIP extension.',	//TODO - Translation
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
-		'disabled' => 'Disabled', // @todo
-		'empty_list' => 'There is no installed extension', // @todo
-		'enabled' => 'Enabled', // @todo
-		'no_configure_view' => 'This extension cannot be configured.', // @todo
+		'author' => 'Author',	//TODO - Translation
+		'community' => 'Available community extensions',	//TODO - Translation
+		'description' => 'Description',	//TODO - Translation
+		'disabled' => 'Disabled',	//TODO - Translation
+		'empty_list' => 'There is no installed extension',	//TODO - Translation
+		'enabled' => 'Enabled',	//TODO - Translation
+		'latest' => 'Installed',	//TODO - Translation
+		'name' => 'Name',	//TODO - Translation
+		'no_configure_view' => 'This extension cannot be configured.',	//TODO - Translation
 		'system' => array(
 		'system' => array(
-			'_' => 'System extensions', // @todo
-			'no_rights' => 'System extension (you have no rights on it)', // @todo
-		),
-		'title' => 'Extensions', // @todo
-		'user' => 'User extensions', // @todo
-		'community' => 'Available community extensions', // @todo
-		'name' => 'Name', // @todo
-		'version' => 'Version', // @todo
-		'description' => 'Description', // @todo
-		'author' => 'Author', // @todo
-		'latest' => 'Installed', // @todo
-		'update' => 'Update available', // @todo
+			'_' => 'System extensions',	//TODO - Translation
+			'no_rights' => 'System extension (you have no rights on it)',	//TODO - Translation
+		),
+		'title' => 'Extensions',	//TODO - Translation
+		'update' => 'Update available',	//TODO - Translation
+		'user' => 'User extensions',	//TODO - Translation
+		'version' => 'Version',	//TODO - Translation
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'סטטיסטיקות',
 		'_' => 'סטטיסטיקות',
@@ -131,9 +131,9 @@ return array(
 		'entry_count' => 'סכום המאמרים',
 		'entry_count' => 'סכום המאמרים',
 		'entry_per_category' => 'מאמרים על פי קטגוריה',
 		'entry_per_category' => 'מאמרים על פי קטגוריה',
 		'entry_per_day' => 'מספר מאמרים ליום (30 ימים אחרונים)',
 		'entry_per_day' => 'מספר מאמרים ליום (30 ימים אחרונים)',
-		'entry_per_day_of_week' => 'Per day of week (average: %.2f messages)', // @todo
-		'entry_per_hour' => 'Per hour (average: %.2f messages)', // @todo
-		'entry_per_month' => 'Per month (average: %.2f messages)', // @todo
+		'entry_per_day_of_week' => 'Per day of week (average: %.2f messages)',	//TODO - Translation
+		'entry_per_hour' => 'Per hour (average: %.2f messages)',	//TODO - Translation
+		'entry_per_month' => 'Per month (average: %.2f messages)',	//TODO - Translation
 		'entry_repartition' => 'חלוקת המאמרים',
 		'entry_repartition' => 'חלוקת המאמרים',
 		'feed' => 'הזנה',
 		'feed' => 'הזנה',
 		'feed_per_category' => 'הזנות על פי קטגוריה',
 		'feed_per_category' => 'הזנות על פי קטגוריה',
@@ -157,37 +157,41 @@ return array(
 		'top_feed' => 'עשרת ההזנות המובילות',
 		'top_feed' => 'עשרת ההזנות המובילות',
 	),
 	),
 	'system' => array(
 	'system' => array(
-		'_' => 'System configuration', // @todo
-		'auto-update-url' => 'Auto-update server URL', // @todo
-		'instance-name' => 'Instance name', // @todo
-		'max-categories' => 'Categories per user limit', // @todo
-		'max-feeds' => 'Feeds per user limit', // @todo
+		'_' => 'System configuration', //TODO - Translation
+		'auto-update-url' => 'Auto-update server URL', //TODO - Translation
+		'cookie-duration' => array(
+			'help' => 'in seconds', //TODO - Translation
+			'number' => 'Duration to keep logged in', //TODO - Translation
+		),
+		'instance-name' => 'Instance name', //TODO - Translation
+		'max-categories' => 'Categories per user limit', //TODO - Translation
+		'max-feeds' => 'Feeds per user limit', //TODO - Translation
 		'registration' => array(
 		'registration' => array(
-			'help' => '0 means that there is no account limit', // @todo
-			'number' => 'Max number of accounts', // @todo
+			'help' => '0 means that there is no account limit',	//TODO - Translation
+			'number' => 'Max number of accounts',	//TODO - Translation
 		),
 		),
 	),
 	),
 	'update' => array(
 	'update' => array(
 		'_' => 'מערכת העדכון',
 		'_' => 'מערכת העדכון',
 		'apply' => 'החלת העדכון',
 		'apply' => 'החלת העדכון',
 		'check' => 'בדיקת עדכונים חדשים',
 		'check' => 'בדיקת עדכונים חדשים',
-		'current_version' => 'Your current version of FreshRSS is the %s.', // @todo
+		'current_version' => 'Your current version of FreshRSS is the %s.',	//TODO - Translation
 		'last' => 'תאריך בדיקה אחרון: %s',
 		'last' => 'תאריך בדיקה אחרון: %s',
 		'none' => 'אין עדכון להחלה',
 		'none' => 'אין עדכון להחלה',
 		'title' => 'מערכת העדכון',
 		'title' => 'מערכת העדכון',
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'articles_and_size' => '%s articles (%s)', // @todo
+		'articles_and_size' => '%s articles (%s)',	//TODO - Translation
 		'create' => 'יצירת משתמש חדש',
 		'create' => 'יצירת משתמש חדש',
-		'delete_users' => 'Delete user', // TODO
+		'delete_users' => 'Delete user',	//TODO - Translation
 		'language' => 'שפה',
 		'language' => 'שפה',
-		'number' => 'There is %d account created', // @todo
-		'numbers' => 'There are %d accounts created', // @todo
+		'number' => 'There is %d account created',	//TODO - Translation
+		'numbers' => 'There are %d accounts created',	//TODO - Translation
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
-		'password_format' => 'At least 7 characters', // @todo
-		'selected' => 'Selected user', // TODO
-		'title' => 'Manage users', // @todo
-		'update_users' => 'Update user', // TODO
+		'password_format' => 'At least 7 characters',	//TODO - Translation
+		'selected' => 'Selected user',	//TODO - Translation
+		'title' => 'Manage users',	//TODO - Translation
+		'update_users' => 'Update user',	//TODO - Translation
 		'user_list' => 'רשימת משתמשים',
 		'user_list' => 'רשימת משתמשים',
 		'username' => 'שם משתמש',
 		'username' => 'שם משתמש',
 		'users' => 'משתמשים',
 		'users' => 'משתמשים',

+ 32 - 26
app/i18n/he/conf.php

@@ -6,7 +6,7 @@ return array(
 		'advanced' => 'מתקדם',
 		'advanced' => 'מתקדם',
 		'delete_after' => 'מחיקת מאמרים לאחר',
 		'delete_after' => 'מחיקת מאמרים לאחר',
 		'help' => 'אפשרויות נוספות זמינות בזרמים ספציפיים',
 		'help' => 'אפשרויות נוספות זמינות בזרמים ספציפיים',
-		'keep_history_by_feed' => 'Minimum number of articles to keep by feed', // @todo
+		'keep_history_by_feed' => 'Minimum number of articles to keep by feed',	//TODO - Translation
 		'optimize' => 'מיטוב בסיס הנתונים',
 		'optimize' => 'מיטוב בסיס הנתונים',
 		'optimize_help' => 'ביצוע לעיתים קרובות על מנת למטב את בסיס הנתונים',
 		'optimize_help' => 'ביצוע לעיתים קרובות על מנת למטב את בסיס הנתונים',
 		'purge_now' => 'ניקוי עכשיו',
 		'purge_now' => 'ניקוי עכשיו',
@@ -19,7 +19,7 @@ return array(
 			'bottom_line' => 'שורה תחתונה',
 			'bottom_line' => 'שורה תחתונה',
 			'entry' => 'סמלילי מאמרים',
 			'entry' => 'סמלילי מאמרים',
 			'publication_date' => 'תאריך הפרסום',
 			'publication_date' => 'תאריך הפרסום',
-			'related_tags' => 'תגיות קשורות',	//TODO
+			'related_tags' => 'תגיות קשורות',	//TODO - Translation
 			'sharing' => 'שיתוף',
 			'sharing' => 'שיתוף',
 			'top_line' => 'שורה עליונה',
 			'top_line' => 'שורה עליונה',
 		),
 		),
@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'שניות (0 משמעותה ללא פג תוקף)',
 			'seconds' => 'שניות (0 משמעותה ללא פג תוקף)',
 			'timeout' => 'HTML5 התראה פג תוקף',
 			'timeout' => 'HTML5 התראה פג תוקף',
 		),
 		),
+		'show_nav_buttons' => 'Show the navigation buttons',	//TODO - Translation
 		'theme' => 'ערכת נושא',
 		'theme' => 'ערכת נושא',
 		'title' => 'תצוגה',
 		'title' => 'תצוגה',
 		'width' => array(
 		'width' => array(
@@ -37,12 +38,22 @@ return array(
 			'no_limit' => 'ללא הגבלה',
 			'no_limit' => 'ללא הגבלה',
 			'thin' => 'צר',
 			'thin' => 'צר',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	//TODO
+	),
+	'profile' => array(
+		'_' => 'Profile management',	//TODO - Translation
+		'delete' => array(
+			'_' => 'Account deletion',	//TODO - Translation
+			'warn' => 'Your account and all related data will be deleted.',	//TODO - Translation
+		),
+		'password_api' => 'סיסמת API<br /><small>(לדוגמה ליישומים סלולריים)</small>',
+		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
+		'password_format' => 'At least 7 characters',	//TODO - Translation
+		'title' => 'Profile',	//TODO - Translation
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'שאילתות',
 		'_' => 'שאילתות',
 		'deprecated' => 'שאילתה זו אינה בתוקף יותר, הפיד או הקטגוריה לייחוס נמחקו.',
 		'deprecated' => 'שאילתה זו אינה בתוקף יותר, הפיד או הקטגוריה לייחוס נמחקו.',
-		'display' => 'Display user query results', // TODO
+		'display' => 'Display user query results',	//TODO - Translation
 		'filter' => 'מסננים בשימוש:',
 		'filter' => 'מסננים בשימוש:',
 		'get_all' => 'הצגת כל המאמרים',
 		'get_all' => 'הצגת כל המאמרים',
 		'get_category' => 'הצגת קטגוריה "%s"',
 		'get_category' => 'הצגת קטגוריה "%s"',
@@ -53,7 +64,7 @@ return array(
 		'number' => 'שאילתה מספר °%d',
 		'number' => 'שאילתה מספר °%d',
 		'order_asc' => 'הצגת מאמרים ישנים בראש',
 		'order_asc' => 'הצגת מאמרים ישנים בראש',
 		'order_desc' => 'הצגת מאמרים חדשים בראש',
 		'order_desc' => 'הצגת מאמרים חדשים בראש',
-		'remove' => 'Remove user query', // TODO
+		'remove' => 'Remove user query',	//TODO - Translation
 		'search' => 'חיפוש "%s"',
 		'search' => 'חיפוש "%s"',
 		'state_0' => 'הצגת כל המאמרים',
 		'state_0' => 'הצגת כל המאמרים',
 		'state_1' => 'הצגת מאמרים שנקראו',
 		'state_1' => 'הצגת מאמרים שנקראו',
@@ -73,28 +84,19 @@ return array(
 		'state_15' => 'הצגת  כל המאמרים',
 		'state_15' => 'הצגת  כל המאמרים',
 		'title' => 'שאילתות',
 		'title' => 'שאילתות',
 	),
 	),
-	'profile' => array(
-		'_' => 'Profile management', // @todo
-		'email_persona' => 'כתובת דואר אלקטרוני להרשמה<br /><small>(לצורך <a href="https://persona.org/" rel="external">מוזילה פרסונה</a>)</small>',
-		'password_api' => 'סיסמת API<br /><small>(לדוגמה ליישומים סלולריים)</small>',
-		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
-		'password_format' => 'At least 7 characters', // @todo
-		'title' => 'Profile', // @todo
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'קריאה',
 		'_' => 'קריאה',
 		'after_onread' => 'לאחר “סימון הכל כנקרא”,',
 		'after_onread' => 'לאחר “סימון הכל כנקרא”,',
 		'articles_per_page' => 'מספר המאמרים בעמוד',
 		'articles_per_page' => 'מספר המאמרים בעמוד',
 		'auto_load_more' => 'טעינת המאמר הבא סוף העמוד',
 		'auto_load_more' => 'טעינת המאמר הבא סוף העמוד',
-		'auto_remove_article' => 'Hide articles after reading', // @todo
-		'mark_updated_article_unread' => 'Mark updated articles as unread', // @todo
+		'auto_remove_article' => 'Hide articles after reading',	//TODO - Translation
 		'confirm_enabled' => 'הצגת דו-שיח לאישור “סימון הכל כנקרא” ',
 		'confirm_enabled' => 'הצגת דו-שיח לאישור “סימון הכל כנקרא” ',
 		'display_articles_unfolded' => 'הצגת מאמרים בשלמותם כברירת מחדל',
 		'display_articles_unfolded' => 'הצגת מאמרים בשלמותם כברירת מחדל',
 		'display_categories_unfolded' => 'הצגת קטגוריות מקופלות כברירת מחדל',
 		'display_categories_unfolded' => 'הצגת קטגוריות מקופלות כברירת מחדל',
 		'hide_read_feeds' => 'הסתרת קטגוריות &amp; הזנות ללא מאמרים שלא נקראו (לא עובד יחד עם “הצגת כל המאמרים”)',
 		'hide_read_feeds' => 'הסתרת קטגוריות &amp; הזנות ללא מאמרים שלא נקראו (לא עובד יחד עם “הצגת כל המאמרים”)',
 		'img_with_lazyload' => 'שימוש ב "טעינה עצלה" על מנת לטעון תמונות',
 		'img_with_lazyload' => 'שימוש ב "טעינה עצלה" על מנת לטעון תמונות',
-		'sides_close_article' => 'Clicking outside of article text area closes the article', // @todo
 		'jump_next' => 'קפיצה לפריט הבא שלא נקרא (הזנה או קטגוריה)',
 		'jump_next' => 'קפיצה לפריט הבא שלא נקרא (הזנה או קטגוריה)',
+		'mark_updated_article_unread' => 'Mark updated articles as unread',	//TODO - Translation
 		'number_divided_when_reader' => 'חלוקה ב2 במצב קריאה.',
 		'number_divided_when_reader' => 'חלוקה ב2 במצב קריאה.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'כאשר מאמר נפתח באתר המקורי',
 			'article_open_on_website' => 'כאשר מאמר נפתח באתר המקורי',
@@ -109,6 +111,7 @@ return array(
 			'all_articles' => 'הצגת כל המאמרים',
 			'all_articles' => 'הצגת כל המאמרים',
 			'unread' => 'הצגת מאמרים שלא נקראו בלבד',
 			'unread' => 'הצגת מאמרים שלא נקראו בלבד',
 		),
 		),
+		'sides_close_article' => 'Clicking outside of article text area closes the article',	//TODO - Translation
 		'sort' => array(
 		'sort' => array(
 			'_' => 'סדר המיון',
 			'_' => 'סדר המיון',
 			'newer_first' => 'חדשים בראש',
 			'newer_first' => 'חדשים בראש',
@@ -125,7 +128,7 @@ return array(
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'שיתוף',
 		'_' => 'שיתוף',
-		'add' => 'Add a sharing method', // TODO
+		'add' => 'Add a sharing method',	//TODO - Translation
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'דואר אלקטרוני',
 		'email' => 'דואר אלקטרוני',
@@ -133,7 +136,7 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'more_information' => 'מידע נוסף',
 		'more_information' => 'מידע נוסף',
 		'print' => 'הדפסה',
 		'print' => 'הדפסה',
-		'remove' => 'Remove sharing method', // TODO
+		'remove' => 'Remove sharing method',	//TODO - Translation
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
 		'share_name' => 'שיתוף שם לתצוגה',
 		'share_name' => 'שיתוף שם לתצוגה',
 		'share_url' => 'לשימוש שתפו URL',
 		'share_url' => 'לשימוש שתפו URL',
@@ -146,34 +149,37 @@ return array(
 		'article_action' => 'פעולות על מאמרים',
 		'article_action' => 'פעולות על מאמרים',
 		'auto_share' => 'שיתוף',
 		'auto_share' => 'שיתוף',
 		'auto_share_help' => 'אם יש רק מצב שיתוף אחד, הוא מופעל. אחרת המצבים נבחרים על בסיס המספר שלהם.',
 		'auto_share_help' => 'אם יש רק מצב שיתוף אחד, הוא מופעל. אחרת המצבים נבחרים על בסיס המספר שלהם.',
-		'close_dropdown' => 'Close menus', // @todo
+		'close_dropdown' => 'Close menus',	//TODO - Translation
 		'collapse_article' => 'כיווץ',
 		'collapse_article' => 'כיווץ',
 		'first_article' => 'דילוג למאמר הראשון',
 		'first_article' => 'דילוג למאמר הראשון',
 		'focus_search' => 'גישה לתיבת החיפוש',
 		'focus_search' => 'גישה לתיבת החיפוש',
-		'global_view' => 'Switch to global view', // TODO
+		'global_view' => 'Switch to global view',	//TODO - Translation
 		'help' => 'הצגת התיעוד',
 		'help' => 'הצגת התיעוד',
 		'javascript' => 'חובה להפעיל JavaScript על מנת לעשות שימוש בקיצורי דרך',
 		'javascript' => 'חובה להפעיל JavaScript על מנת לעשות שימוש בקיצורי דרך',
 		'last_article' => 'דילוג למאמר האחרון',
 		'last_article' => 'דילוג למאמר האחרון',
 		'load_more' => 'טעינת מאמרים נוספים',
 		'load_more' => 'טעינת מאמרים נוספים',
-		'mark_read' => 'סימון כנקרא',
 		'mark_favorite' => 'סימון כמועדף',
 		'mark_favorite' => 'סימון כמועדף',
+		'mark_read' => 'סימון כנקרא',
 		'navigation' => 'ניווט',
 		'navigation' => 'ניווט',
 		'navigation_help' => 'בעזרת מקש השיפט קיצורי דרך חלים על הזנות .<br/>עם מקש האלט הם חלים על קטגוריות.',
 		'navigation_help' => 'בעזרת מקש השיפט קיצורי דרך חלים על הזנות .<br/>עם מקש האלט הם חלים על קטגוריות.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => 'דילוג למאמר הבא',
 		'next_article' => 'דילוג למאמר הבא',
-		'normal_view' => 'Switch to normal view', // TODO
+		'normal_view' => 'Switch to normal view',	//TODO - Translation
 		'other_action' => 'פעולות אחרות',
 		'other_action' => 'פעולות אחרות',
 		'previous_article' => 'דילוג למאמר הקודם',
 		'previous_article' => 'דילוג למאמר הקודם',
-		'reading_view' => 'Switch to reading view', // TODO
-		'rss_view' => 'Open RSS view in a new tab', // TODO
+		'reading_view' => 'Switch to reading view',	//TODO - Translation
+		'rss_view' => 'Open RSS view in a new tab',	//TODO - Translation
 		'see_on_website' => 'ראו את המקור באתר',
 		'see_on_website' => 'ראו את המקור באתר',
 		'shift_for_all_read' => '+ <code>shift</code> על מנת לסמן את כל המאמרים כנקראו',
 		'shift_for_all_read' => '+ <code>shift</code> על מנת לסמן את כל המאמרים כנקראו',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => 'קיצורי דרך',
 		'title' => 'קיצורי דרך',
 		'user_filter' => 'גישה למססנים',
 		'user_filter' => 'גישה למססנים',
 		'user_filter_help' => 'אם יש רק מזנן אחד הוא יהיה בשימוש. אחרת המסננים ישמשו על בסיס המספר שלהם.',
 		'user_filter_help' => 'אם יש רק מזנן אחד הוא יהיה בשימוש. אחרת המסננים ישמשו על בסיס המספר שלהם.',
-		'views' => 'Views', // TODO
+		'views' => 'Views',	//TODO - Translation
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'articles_and_size' => '%s articles (%s)', // @todo
+		'articles_and_size' => '%s articles (%s)',	//TODO - Translation
 		'current' => 'משתמש נוכחי',
 		'current' => 'משתמש נוכחי',
 		'is_admin' => 'מנהל',
 		'is_admin' => 'מנהל',
 		'users' => 'משתמשים',
 		'users' => 'משתמשים',

+ 24 - 25
app/i18n/he/feedback.php

@@ -21,7 +21,6 @@ return array(
 			'success' => 'You are disconnected', // @todo
 			'success' => 'You are disconnected', // @todo
 		),
 		),
 		'no_password_set' => 'לא הוגדרה סיסמת מנהל. תכונה זו אינה זמינה.',
 		'no_password_set' => 'לא הוגדרה סיסמת מנהל. תכונה זו אינה זמינה.',
-		'not_persona' => 'ניתן לאפס את מערכת הפרסונה בלבד.',
 	),
 	),
 	'conf' => array(
 	'conf' => array(
 		'error' => 'An error occurred during configuration saving', // @todo
 		'error' => 'An error occurred during configuration saving', // @todo
@@ -51,24 +50,28 @@ return array(
 		'no_zip_extension' => 'הרחבת ZIP אינה מותקנת על השרת.',
 		'no_zip_extension' => 'הרחבת ZIP אינה מותקנת על השרת.',
 		'zip_error' => 'אירעה שגיאה במהלך ייבוא קובץ הZIP.',
 		'zip_error' => 'אירעה שגיאה במהלך ייבוא קובץ הZIP.',
 	),
 	),
+	'profile' => array(
+		'error' => 'Your profile cannot be modified', // @todo
+		'updated' => 'Your profile has been modified', // @todo
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'מימוש',
 		'actualize' => 'מימוש',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	//TODO
-			'marked_unread' => 'The articles have been marked as unread.',	//TODO
+			'marked_read' => 'The selected articles have been marked as read.',	//TODO - Translation
+			'marked_unread' => 'The articles have been marked as unread.',	//TODO - Translation
 		),
 		),
 		'category' => array(
 		'category' => array(
-			'created' => 'Category %s has been created.', // @todo
-			'deleted' => 'Category has been deleted.', // @todo
+			'created' => 'Category %s has been created.',	//TODO - Translation
+			'deleted' => 'Category has been deleted.',	//TODO - Translation
 			'emptied' => 'הקטגוריה רוקנה',
 			'emptied' => 'הקטגוריה רוקנה',
-			'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
+			'error' => 'Category cannot be updated',	//TODO - Translation
+			'name_exists' => 'Category name already exists.',	//TODO - Translation
+			'no_id' => 'You must precise the id of the category.',	//TODO - Translation
+			'no_name' => 'Category name cannot be empty.',	//TODO - Translation
+			'not_delete_default' => 'You cannot delete the default category!',	//TODO - Translation
+			'not_exist' => 'The category does not exist!',	//TODO - Translation
+			'over_max' => 'You have reached your limit of categories (%d)',	//TODO - Translation
+			'updated' => 'Category has been updated.',	//TODO - Translation
 		),
 		),
 		'feed' => array(
 		'feed' => array(
 			'actualized' => '<em>%s</em> עודכן',
 			'actualized' => '<em>%s</em> עודכן',
@@ -76,20 +79,20 @@ return array(
 			'added' => 'RSS הזנת <em>%s</em> נוספה',
 			'added' => 'RSS הזנת <em>%s</em> נוספה',
 			'already_subscribed' => 'אתה כבר רשום ל <em>%s</em>',
 			'already_subscribed' => 'אתה כבר רשום ל <em>%s</em>',
 			'deleted' => 'ההזנה נמחקה',
 			'deleted' => 'ההזנה נמחקה',
-			'error' => 'Feed cannot be updated', // @todo
-			'internal_problem' => 'אין אפשרות להוסיף את ההזנה. <a href="%s">בדקו את הלוגים</a> לפרטים.', // @todo
+			'error' => 'Feed cannot be updated',	//TODO - Translation
+			'internal_problem' => 'אין אפשרות להוסיף את ההזנה. <a href="%s">בדקו את הלוגים</a> לפרטים.',	//TODO - Translation
 			'invalid_url' => 'URL <em>%s</em> אינו תקין',
 			'invalid_url' => 'URL <em>%s</em> אינו תקין',
 			'n_actualized' => '%d הזנות עודכנו',
 			'n_actualized' => '%d הזנות עודכנו',
 			'n_entries_deleted' => '%d המאמרים נמחקו',
 			'n_entries_deleted' => '%d המאמרים נמחקו',
 			'no_refresh' => 'אין הזנה שניתן לרענן…',
 			'no_refresh' => 'אין הזנה שניתן לרענן…',
 			'not_added' => '<em>%s</em> אין אפשרות להוסיף את',
 			'not_added' => '<em>%s</em> אין אפשרות להוסיף את',
-			'over_max' => 'You have reached your limit of feeds (%d)', // @todo
+			'over_max' => 'You have reached your limit of feeds (%d)',	//TODO - Translation
 			'updated' => 'ההזנה התעדכנה',
 			'updated' => 'ההזנה התעדכנה',
 		),
 		),
 		'purge_completed' => 'הניקוי הושלם (%d מאמרים נמחקו)',
 		'purge_completed' => 'הניקוי הושלם (%d מאמרים נמחקו)',
 	),
 	),
 	'update' => array(
 	'update' => array(
-		'can_apply' => 'FreshRSS will be now updated to the <strong>version %s</strong>.', // @todo
+		'can_apply' => 'FreshRSS will be now updated to the <strong>version %s</strong>.',	//TODO - Translation
 		'error' => 'תהליך העדכון נתקל בשגיאה: %s',
 		'error' => 'תהליך העדכון נתקל בשגיאה: %s',
 		'file_is_nok' => 'יש לבדוק את ההרשאות בתיקייה <em>%s</em>. שרת הHTTP חייב להיות בעל הרשאות כתיבה.',
 		'file_is_nok' => 'יש לבדוק את ההרשאות בתיקייה <em>%s</em>. שרת הHTTP חייב להיות בעל הרשאות כתיבה.',
 		'finished' => 'העדכון הושלם!',
 		'finished' => 'העדכון הושלם!',
@@ -99,19 +102,15 @@ return array(
 	'user' => array(
 	'user' => array(
 		'created' => array(
 		'created' => array(
 			'_' => 'המשתמש %s נוצר',
 			'_' => 'המשתמש %s נוצר',
-			'error' => 'User %s cannot be created', // @todo
+			'error' => 'User %s cannot be created',	//TODO - Translation
 		),
 		),
 		'deleted' => array(
 		'deleted' => array(
 			'_' => 'המשתמש %s נמחק',
 			'_' => 'המשתמש %s נמחק',
-			'error' => 'User %s cannot be deleted', // @todo
+			'error' => 'User %s cannot be deleted',	//TODO - Translation
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated', // TODO
-			'error' => 'User %s has not been updated', // TODO
+			'_' => 'User %s has been updated',	//TODO - Translation
+			'error' => 'User %s has not been updated',	//TODO - Translation
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => 'Your profile cannot be modified', // @todo
-		'updated' => 'Your profile has been modified', // @todo
-	),
 );
 );

+ 32 - 30
app/i18n/he/gen.php

@@ -6,23 +6,23 @@ return array(
 		'back_to_rss_feeds' => '← חזרה להזנות הRSS שלך',
 		'back_to_rss_feeds' => '← חזרה להזנות הRSS שלך',
 		'cancel' => 'ביטול',
 		'cancel' => 'ביטול',
 		'create' => 'יצירה',
 		'create' => 'יצירה',
-		'disable' => 'Disable', // @todo
-		'empty' => 'Empty', // @todo
-		'enable' => 'Enable', // @todo
+		'disable' => 'Disable',	//TODO - Translation
+		'empty' => 'Empty',	//TODO - Translation
+		'enable' => 'Enable',	//TODO - Translation
 		'export' => 'ייצוא',
 		'export' => 'ייצוא',
 		'filter' => 'מסנן',
 		'filter' => 'מסנן',
 		'import' => 'ייבוא',
 		'import' => 'ייבוא',
 		'manage' => 'ניהול',
 		'manage' => 'ניהול',
 		'mark_read' => 'סימון כנקרא',
 		'mark_read' => 'סימון כנקרא',
 		'mark_favorite' => 'סימון כמועדף',
 		'mark_favorite' => 'סימון כמועדף',
-		'remove' => 'Remove', // @todo
+		'remove' => 'Remove',	//TODO - Translation
 		'see_website' => 'ראו אתר',
 		'see_website' => 'ראו אתר',
 		'submit' => 'אישור',
 		'submit' => 'אישור',
 		'truncate' => 'מחיקת כל המאמרים',
 		'truncate' => 'מחיקת כל המאמרים',
-		'update' => 'Update', // TODO
+		'update' => 'Update',	//TODO - Translation
 	),
 	),
 	'auth' => array(
 	'auth' => array(
-		'email' => 'Email address', // @todo
+		'email' => 'Email address',	//TODO - Translation
 		'keep_logged_in' => 'השאר מחובר <small>חודש</small>',
 		'keep_logged_in' => 'השאר מחובר <small>חודש</small>',
 		'login' => 'כניסה לחשבון',
 		'login' => 'כניסה לחשבון',
 		'logout' => 'יציאה מהחשבון',
 		'logout' => 'יציאה מהחשבון',
@@ -31,46 +31,41 @@ return array(
 			'format' => '<small>At least 7 characters</small>',
 			'format' => '<small>At least 7 characters</small>',
 		),
 		),
 		'registration' => array(
 		'registration' => array(
-			'_' => 'New account', // @todo
-			'ask' => 'Create an account?', // @todo
-			'title' => 'Account creation', // @todo
+			'_' => 'New account',	//TODO - Translation
+			'ask' => 'Create an account?',	//TODO - Translation
+			'title' => 'Account creation',	//TODO - Translation
 		),
 		),
 		'reset' => 'איפוס אימות',
 		'reset' => 'איפוס אימות',
 		'username' => array(
 		'username' => array(
 			'_' => 'שם משתמש',
 			'_' => 'שם משתמש',
 			'admin' => 'שם משתמש של המנהל',
 			'admin' => 'שם משתמש של המנהל',
-			'format' => '<small>maximum 16 alphanumeric characters</small>', // @todo
+			'format' => '<small>maximum 16 alphanumeric characters</small>',	//TODO - Translation
 		),
 		),
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\A\\p\\r\\i\\l',
 		'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' => 'apr',
 		'apr' => 'apr',
 		'april' => 'Apr',
 		'april' => 'Apr',
+		'Aug' => '\\A\\u\\g\\u\\s\\t',
 		'aug' => 'aug',
 		'aug' => 'aug',
 		'august' => 'Aug',
 		'august' => 'Aug',
 		'before_yesterday' => 'ישן יותר',
 		'before_yesterday' => 'ישן יותר',
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
 		'dec' => 'dec',
 		'dec' => 'dec',
 		'december' => 'Dec',
 		'december' => 'Dec',
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',
 		'feb' => 'feb',
 		'feb' => 'feb',
 		'february' => 'Feb',
 		'february' => 'Feb',
 		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
 		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
 		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',
 		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',
 		'fri' => 'Fri',
 		'fri' => 'Fri',
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',
 		'jan' => 'jan',
 		'jan' => 'jan',
 		'january' => 'Jan',
 		'january' => 'Jan',
+		'Jul' => '\\J\\u\\l\\y',
 		'jul' => 'jul',
 		'jul' => 'jul',
 		'july' => 'Jul',
 		'july' => 'Jul',
+		'Jun' => '\\J\\u\\n\\e',
 		'jun' => 'jun',
 		'jun' => 'jun',
 		'june' => 'Jun',
 		'june' => 'Jun',
 		'last_3_month' => 'בשלושת החודשים האחרונים',
 		'last_3_month' => 'בשלושת החודשים האחרונים',
@@ -78,17 +73,22 @@ return array(
 		'last_month' => 'בחודש שעבר',
 		'last_month' => 'בחודש שעבר',
 		'last_week' => 'בשבוע שעבר',
 		'last_week' => 'בשבוע שעבר',
 		'last_year' => 'בשנה האחרונה',
 		'last_year' => 'בשנה האחרונה',
+		'Mar' => '\\M\\a\\r\\c\\h',
 		'mar' => 'mar',
 		'mar' => 'mar',
 		'march' => 'Mar',
 		'march' => 'Mar',
+		'May' => '\\M\\a\\y',
 		'may' => 'May',
 		'may' => 'May',
 		'may_' => 'May',
 		'may_' => 'May',
 		'mon' => 'Mon',
 		'mon' => 'Mon',
 		'month' => 'חודשים',
 		'month' => 'חודשים',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
 		'nov' => 'nov',
 		'nov' => 'nov',
 		'november' => 'Nov',
 		'november' => 'Nov',
+		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',
 		'oct' => 'oct',
 		'oct' => 'oct',
 		'october' => 'Oct',
 		'october' => 'Oct',
 		'sat' => 'Sat',
 		'sat' => 'Sat',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
 		'sep' => 'sep',
 		'sep' => 'sep',
 		'september' => 'Sep',
 		'september' => 'Sep',
 		'sun' => 'Sun',
 		'sun' => 'Sun',
@@ -103,12 +103,12 @@ return array(
 		'about' => 'אודות FreshRSS',
 		'about' => 'אודות FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
-		'category_empty' => 'Empty category', // @todo
+		'category_empty' => 'Empty category',	//TODO - Translation
 		'confirm_action' => 'האם אתם בטוחים שברצונכם לבצע פעולה זו? אין אפשרות לבטל אותה!',
 		'confirm_action' => 'האם אתם בטוחים שברצונכם לבצע פעולה זו? אין אפשרות לבטל אותה!',
 		'confirm_action_feed_cat' => 'האם אתם בטוחים שברצוניכם לבצע פעולה זו? מועדפים ושאילתות עשויות לאבוד. אין אפשרות לבטל אותה!',
 		'confirm_action_feed_cat' => 'האם אתם בטוחים שברצוניכם לבצע פעולה זו? מועדפים ושאילתות עשויות לאבוד. אין אפשרות לבטל אותה!',
 		'feedback' => array(
 		'feedback' => array(
 			'body_new_articles' => 'ישנם  \d מאמרים חדשים לקרוא ב FreshRSS.',
 			'body_new_articles' => 'ישנם  \d מאמרים חדשים לקרוא ב FreshRSS.',
-			'request_failed' => 'A request has failed, it may have been caused by Internet connection problems.', // @todo
+			'request_failed' => 'A request has failed, it may have been caused by Internet connection problems.',	//TODO - Translation
 			'title_new_articles' => 'FreshRSS: מאמרים חדשים!',
 			'title_new_articles' => 'FreshRSS: מאמרים חדשים!',
 		),
 		),
 		'new_article' => 'מאמרים חדשים זמינים, לחצו לרענון העמוד.',
 		'new_article' => 'מאמרים חדשים זמינים, לחצו לרענון העמוד.',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -133,11 +134,11 @@ return array(
 		'about' => 'אודות',
 		'about' => 'אודות',
 		'admin' => 'ניהול',
 		'admin' => 'ניהול',
 		'archiving' => 'ארכוב',
 		'archiving' => 'ארכוב',
-		'authentication' => 'Authentication', // @todo
-		'check_install' => 'Installation checking', // @todo
+		'authentication' => 'Authentication',	//TODO - Translation
+		'check_install' => 'Installation checking',	//TODO - Translation
 		'configuration' => 'הגדרות',
 		'configuration' => 'הגדרות',
 		'display' => 'תצוגה',
 		'display' => 'תצוגה',
-		'extensions' => 'Extensions', // @todo
+		'extensions' => 'Extensions',	//TODO - Translation
 		'logs' => 'לוגים',
 		'logs' => 'לוגים',
 		'queries' => 'שאילתות',
 		'queries' => 'שאילתות',
 		'reading' => 'קריאה',
 		'reading' => 'קריאה',
@@ -145,10 +146,10 @@ return array(
 		'sharing' => 'שיתוף',
 		'sharing' => 'שיתוף',
 		'shortcuts' => 'קיצורי דרך',
 		'shortcuts' => 'קיצורי דרך',
 		'stats' => 'סטטיסטיקות',
 		'stats' => 'סטטיסטיקות',
-		'system' => 'System configuration', // @todo
+		'system' => 'System configuration',	//TODO - Translation
 		'update' => 'עדכון',
 		'update' => 'עדכון',
-		'user_management' => 'Manage users', // @todo
-		'user_profile' => 'Profile', // @todo
+		'user_management' => 'Manage users',	//TODO - Translation
+		'user_profile' => 'Profile',	//TODO - Translation
 	),
 	),
 	'pagination' => array(
 	'pagination' => array(
 		'first' => 'הראשון',
 		'first' => 'הראשון',
@@ -171,6 +172,7 @@ return array(
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'הדפסה',
 		'print' => 'הדפסה',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
@@ -186,7 +188,7 @@ return array(
 		'damn' => 'הו לא!',
 		'damn' => 'הו לא!',
 		'default_category' => 'ללא קטגוריה',
 		'default_category' => 'ללא קטגוריה',
 		'no' => 'לא',
 		'no' => 'לא',
-		'not_applicable' => 'Not available', // @todo
+		'not_applicable' => 'Not available',	//TODO - Translation
 		'ok' => 'כן!',
 		'ok' => 'כן!',
 		'or' => 'או',
 		'or' => 'או',
 		'yes' => 'כן',
 		'yes' => 'כן',

+ 3 - 3
app/i18n/he/index.php

@@ -40,7 +40,7 @@ return array(
 		'mark_all_read' => 'סימון הכל כנקרא',
 		'mark_all_read' => 'סימון הכל כנקרא',
 		'mark_cat_read' => 'סימון קטגוריה כנקראה',
 		'mark_cat_read' => 'סימון קטגוריה כנקראה',
 		'mark_feed_read' => 'סימון הזנה כנקראה',
 		'mark_feed_read' => 'סימון הזנה כנקראה',
-		'mark_selection_unread' => 'Mark selection as unread',	//TODO
+		'mark_selection_unread' => 'Mark selection as unread',	//TODO - Translation
 		'newer_first' => 'חדשים בראש',
 		'newer_first' => 'חדשים בראש',
 		'non-starred' => 'הצגת הכל פרט למועדפים',
 		'non-starred' => 'הצגת הכל פרט למועדפים',
 		'normal_view' => 'תצוגה רגילה',
 		'normal_view' => 'תצוגה רגילה',
@@ -53,11 +53,11 @@ return array(
 		'starred' => 'הצגת מועדפים בלבד',
 		'starred' => 'הצגת מועדפים בלבד',
 		'stats' => 'סטטיסטיקות',
 		'stats' => 'סטטיסטיקות',
 		'subscription' => 'ניהול הרשמות',
 		'subscription' => 'ניהול הרשמות',
-		'tags' => 'My labels',	//TODO
+		'tags' => 'My labels',	//TODO - Translation
 		'unread' => 'הצגת מאמרים שלא נקראו בלבד',
 		'unread' => 'הצגת מאמרים שלא נקראו בלבד',
 	),
 	),
 	'share' => 'שיתוף',
 	'share' => 'שיתוף',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'תגיות קשורות',	//TODO
+		'related' => 'תגיות קשורות',	//TODO - Translation
 	),
 	),
 );
 );

+ 28 - 20
app/i18n/he/install.php

@@ -4,16 +4,16 @@ return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'השלמת ההתקנה',
 		'finish' => 'השלמת ההתקנה',
 		'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.',
 		'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.',
+		'keep_install' => 'Keep previous configuration',	//TODO - Translation
 		'next_step' => 'לשלב הבא',
 		'next_step' => 'לשלב הבא',
+		'reinstall' => 'Reinstall FreshRSS',	//TODO - Translation
 	),
 	),
 	'auth' => array(
 	'auth' => array(
-		'email_persona' => 'כתובת דואר אלקטרוני להרשמה<br /><small>(לצורך <a href="https://persona.org/" rel="external">מוזילה פרסונה</a>)</small>',
 		'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)',
 		'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)',
 		'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)',
 		'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)',
 		'none' => 'ללא (מסוכן)',
 		'none' => 'ללא (מסוכן)',
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
-		'password_format' => 'At least 7 characters', // @todo
-		'persona' => 'מוזילה פרסונה (מודרני, דורש JavaScript)',
+		'password_format' => 'At least 7 characters',	//TODO - Translation
 		'type' => 'שיטת אימות',
 		'type' => 'שיטת אימות',
 	),
 	),
 	'bdd' => array(
 	'bdd' => array(
@@ -24,15 +24,16 @@ return array(
 			'ok' => 'הגדרות בסיס הנתונים נשמרו.',
 			'ok' => 'הגדרות בסיס הנתונים נשמרו.',
 		),
 		),
 		'host' => 'מארח',
 		'host' => 'מארח',
-		'prefix' => 'קידומת הטבלה',
 		'password' => 'HTTP סיסמה',
 		'password' => 'HTTP סיסמה',
+		'prefix' => 'קידומת הטבלה',
 		'type' => 'סוג בסיס הנתונים',
 		'type' => 'סוג בסיס הנתונים',
 		'username' => 'HTTP שם משתמש',
 		'username' => 'HTTP שם משתמש',
 	),
 	),
 	'check' => array(
 	'check' => array(
 		'_' => 'בדיקות',
 		'_' => 'בדיקות',
+		'already_installed' => 'We have detected that FreshRSS is already installed!',	//TODO - Translation
 		'cache' => array(
 		'cache' => array(
-			'nok' => 'Check permissions on <em>./data/cache</em> directory. HTTP server must have rights to write into', // @todo
+			'nok' => 'Check permissions on <em>./data/cache</em> directory. HTTP server must have rights to write into',	//TODO - Translation
 			'ok' => 'ההרשאות בתיקיית המטמון תקינות',
 			'ok' => 'ההרשאות בתיקיית המטמון תקינות',
 		),
 		),
 		'ctype' => array(
 		'ctype' => array(
@@ -44,7 +45,7 @@ return array(
 			'ok' => 'יש לכם את גירסת %s של cURL',
 			'ok' => 'יש לכם את גירסת %s של cURL',
 		),
 		),
 		'data' => array(
 		'data' => array(
-			'nok' => 'Check permissions on <em>./data</em> directory. HTTP server must have rights to write into', // @todo
+			'nok' => 'Check permissions on <em>./data</em> directory. HTTP server must have rights to write into',	//TODO - Translation
 			'ok' => 'ההרשאות בתיקיית הדאטא תקינות',
 			'ok' => 'ההרשאות בתיקיית הדאטא תקינות',
 		),
 		),
 		'dom' => array(
 		'dom' => array(
@@ -52,23 +53,27 @@ return array(
 			'ok' => 'הספרייה הנדרשת לסיור ב DOM מותקנת',
 			'ok' => 'הספרייה הנדרשת לסיור ב DOM מותקנת',
 		),
 		),
 		'favicons' => array(
 		'favicons' => array(
-			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have rights to write into', // @todo
+			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have rights to write into',	//TODO - Translation
 			'ok' => 'ההרשאות בתיקיית הfavicons תקינות',
 			'ok' => 'ההרשאות בתיקיית הfavicons תקינות',
 		),
 		),
+		'fileinfo' => array(
+			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	//TODO - Translation
+			'ok' => 'You have the fileinfo library.',	//TODO - Translation
+		),
 		'http_referer' => array(
 		'http_referer' => array(
 			'nok' => 'נא לדבוק שאינך פוגעת ב HTTP REFERER שלך.',
 			'nok' => 'נא לדבוק שאינך פוגעת ב HTTP REFERER שלך.',
 			'ok' => 'הHTTP REFERER ידוע ותאם לשרת שלך.',
 			'ok' => 'הHTTP REFERER ידוע ותאם לשרת שלך.',
 		),
 		),
 		'json' => array(
 		'json' => array(
-			'nok' => 'Cannot find a recommended library to parse JSON.',	//TODO
-			'ok' => 'You have a recommended library to parse JSON.',	//TODO
+			'nok' => 'Cannot find a recommended library to parse JSON.',	//TODO - Translation
+			'ok' => 'You have a recommended library to parse JSON.',	//TODO - Translation
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
-			'nok' => 'You lack the Minz framework.', // @todo
+			'nok' => 'You lack the Minz framework.',	//TODO - Translation
 			'ok' => 'יש לכם את תשתית Minz',
 			'ok' => 'יש לכם את תשתית Minz',
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
@@ -79,17 +84,17 @@ return array(
 			'nok' => 'PDO אינו מותקן או שאחד ממנהלי ההתקנים שלו חסר (pdo_mysql, pdo_sqlite)',
 			'nok' => 'PDO אינו מותקן או שאחד ממנהלי ההתקנים שלו חסר (pdo_mysql, pdo_sqlite)',
 			'ok' => 'PDO מותקן ולפחות אחד ממנהלי ההתקן הנתמכים מותקן (pdo_mysql, pdo_sqlite)',
 			'ok' => 'PDO מותקן ולפחות אחד ממנהלי ההתקן הנתמכים מותקן (pdo_mysql, pdo_sqlite)',
 		),
 		),
-		'persona' => array(
-			'nok' => 'Check permissions on <em>./data/persona</em> directory. HTTP server must have rights to write into', // @todo
-			'ok' => 'ההרשאות בתיקיית מוזילה פרסונה תקינות',
-		),
 		'php' => array(
 		'php' => array(
 			'nok' => 'גירסת PHP שלכם היא %s אך FreshRSS דורש לפחות את גירסה %s',
 			'nok' => 'גירסת PHP שלכם היא %s אך FreshRSS דורש לפחות את גירסה %s',
 			'ok' => 'גירסת PHP שלכם היא %s, שתואמת ל FreshRSS',
 			'ok' => 'גירסת PHP שלכם היא %s, שתואמת ל FreshRSS',
 		),
 		),
 		'users' => array(
 		'users' => array(
-			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have rights to write into', // @todo
-			'ok' => 'Permissions on users directory are good.', // @todo
+			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have rights to write into',	//TODO - Translation
+			'ok' => 'Permissions on users directory are good.',	//TODO - Translation
+		),
+		'xml' => array(
+			'nok' => 'Cannot find the required library to parse XML.',	//TODO - Translation
+			'ok' => 'You have the required library to parse XML.',	//TODO - Translation
 		),
 		),
 	),
 	),
 	'conf' => array(
 	'conf' => array(
@@ -101,14 +106,17 @@ return array(
 	'delete_articles_after' => 'מחיקת מאמרים לאחר',
 	'delete_articles_after' => 'מחיקת מאמרים לאחר',
 	'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.',
 	'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.',
 	'javascript_is_better' => 'FreshRSS מעדיף שתאפשרו JavaScript',
 	'javascript_is_better' => 'FreshRSS מעדיף שתאפשרו JavaScript',
+	'js' => array(
+		'confirm_reinstall' => 'You will lose your previous configuration by reinstalling FreshRSS. Are you sure you want to continue?',	//TODO - Translation
+	),
 	'language' => array(
 	'language' => array(
 		'_' => 'שפה',
 		'_' => 'שפה',
 		'choose' => 'בחירת שפה ל FreshRSS',
 		'choose' => 'בחירת שפה ל FreshRSS',
 		'defined' => 'השפה הוגדרה.',
 		'defined' => 'השפה הוגדרה.',
 	),
 	),
 	'not_deleted' => 'משהו נכשל; יש צורך למחוק את הקובץ <em>%s</em> ידנית.',
 	'not_deleted' => 'משהו נכשל; יש צורך למחוק את הקובץ <em>%s</em> ידנית.',
-	'ok' => 'The installation process was successful.', // @todo
-	'step' => 'step %d', // @todo
+	'ok' => 'The installation process was successful.',	//TODO - Translation
+	'step' => 'step %d',	//TODO - Translation
 	'steps' => 'שלבים',
 	'steps' => 'שלבים',
 	'title' => 'התקנה · FreshRSS',
 	'title' => 'התקנה · FreshRSS',
 	'this_is_the_end' => 'סיום',
 	'this_is_the_end' => 'סיום',

+ 25 - 17
app/i18n/he/sub.php

@@ -2,18 +2,18 @@
 
 
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.', // @todo
-		'title' => 'API', // @todo
+		'documentation' => 'Copy the following URL to use it within an external tool.',	//TODO - Translation
+		'title' => 'API',	//TODO - Translation
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
-		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.', // @todo
-		'label' => 'Subscribe', // @todo
-		'title' => 'Bookmarklet', // @todo
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',	//TODO - Translation
+		'label' => 'Subscribe',	//TODO - Translation
+		'title' => 'Bookmarklet',	//TODO - Translation
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'קטגוריה',
 		'_' => 'קטגוריה',
 		'add' => 'הוספת קטגוריה',
 		'add' => 'הוספת קטגוריה',
-		'empty' => 'Empty category', // @todo
+		'empty' => 'Empty category',	//TODO - Translation
 		'new' => 'קטגוריה חדשה',
 		'new' => 'קטגוריה חדשה',
 	),
 	),
 	'feed' => array(
 	'feed' => array(
@@ -27,7 +27,7 @@ return array(
 			'password' => 'HTTP סיסמה',
 			'password' => 'HTTP סיסמה',
 			'username' => 'HTTP שם משתמש',
 			'username' => 'HTTP שם משתמש',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	//TODO
+		'clear_cache' => 'Always clear cache',	//TODO - Translation
 		'css_help' => 'קבלת הזנות RSS קטומות  (זהירות, לוקח זמן רב יותר!)',
 		'css_help' => 'קבלת הזנות RSS קטומות  (זהירות, לוקח זמן רב יותר!)',
 		'css_path' => 'נתיב הCSS של המאמר באתר המקורי',
 		'css_path' => 'נתיב הCSS של המאמר באתר המקורי',
 		'description' => 'תיאור',
 		'description' => 'תיאור',
@@ -36,19 +36,27 @@ return array(
 		'informations' => 'מידע',
 		'informations' => 'מידע',
 		'keep_history' => 'מסםר מינימלי של מאמרים לשמור',
 		'keep_history' => 'מסםר מינימלי של מאמרים לשמור',
 		'moved_category_deleted' => 'כאשר הקטגוריה נמחקת ההזנות שבתוכה אוטומטית מקוטלגות תחת  <em>%s</em>.',
 		'moved_category_deleted' => 'כאשר הקטגוריה נמחקת ההזנות שבתוכה אוטומטית מקוטלגות תחת  <em>%s</em>.',
-		'mute' => 'mute', // TODO
+		'mute' => 'mute',	//TODO - Translation
 		'no_selected' => 'אף הזנה לא נבחרה.',
 		'no_selected' => 'אף הזנה לא נבחרה.',
 		'number_entries' => '%d מאמרים',
 		'number_entries' => '%d מאמרים',
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility', // TODO
-			'archived' => 'Do not show (archived)', // TODO
+			'_' => 'Visibility',	//TODO - Translation
+			'archived' => 'Do not show (archived)',	//TODO - Translation
 			'main_stream' => 'הצגה בזרם המרכזי',
 			'main_stream' => 'הצגה בזרם המרכזי',
-			'normal' => 'Show in its category', // TODO
+			'normal' => 'Show in its category',	//TODO - Translation
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	//TODO
+		'websub' => 'Instant notification with WebSub',	//TODO - Translation
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
+		'ssl_verify' => 'Verify SSL security',	//TODO - Translation
 		'stats' => 'סטטיסטיקות',
 		'stats' => 'סטטיסטיקות',
 		'think_to_add' => 'ניתן להוסיף הזנות חדשות.',
 		'think_to_add' => 'ניתן להוסיף הזנות חדשות.',
-		'timeout' => 'Timeout in seconds',	//TODO
+		'timeout' => 'Timeout in seconds',	//TODO - Translation
 		'title' => 'כותרת',
 		'title' => 'כותרת',
 		'title_add' => 'הוספת הזנה',
 		'title_add' => 'הוספת הזנה',
 		'ttl' => 'אין לרענן אוטומטית יותר מ',
 		'ttl' => 'אין לרענן אוטומטית יותר מ',
@@ -57,8 +65,8 @@ return array(
 		'website' => 'אתר URL',
 		'website' => 'אתר URL',
 	),
 	),
 	'firefox' => array(
 	'firefox' => array(
-		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.', // @todo
-		'title' => 'Firefox feed reader', // @todo
+		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',	//TODO - Translation
+		'title' => 'Firefox feed reader',	//TODO - Translation
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export' => 'ייצוא',
 		'export' => 'ייצוא',
@@ -75,11 +83,11 @@ return array(
 		'bookmark' => 'הרשמה (FreshRSS סימניית)',
 		'bookmark' => 'הרשמה (FreshRSS סימניית)',
 		'import_export' => 'יבוא / יצוא ',
 		'import_export' => 'יבוא / יצוא ',
 		'subscription_management' => 'ניהול הרשמות',
 		'subscription_management' => 'ניהול הרשמות',
-		'subscription_tools' => 'Subscription tools', // @todo
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 	'title' => array(
 	'title' => array(
 		'_' => 'ניהול הרשמות',
 		'_' => 'ניהול הרשמות',
 		'feed_management' => 'ניהול הזנות RSS',
 		'feed_management' => 'ניהול הזנות RSS',
-		'subscription_tools' => 'Subscription tools', // @todo
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 );
 );

+ 17 - 13
app/i18n/it/admin.php

@@ -67,8 +67,8 @@ return array(
 			'ok' => 'Estensione JSON presente.',
 			'ok' => 'Estensione JSON presente.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Manca il framework Minz.',
 			'nok' => 'Manca il framework Minz.',
@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Author',	//TODO - Translation
+		'community' => 'Available community extensions',	//TODO - Translation
+		'description' => 'Description',	//TODO - Translation
 		'disabled' => 'Disabilitata',
 		'disabled' => 'Disabilitata',
 		'empty_list' => 'Non ci sono estensioni installate',
 		'empty_list' => 'Non ci sono estensioni installate',
 		'enabled' => 'Abilitata',
 		'enabled' => 'Abilitata',
+		'latest' => 'Installed',	//TODO - Translation
+		'name' => 'Name',	//TODO - Translation
 		'no_configure_view' => 'Questa estensioni non può essere configurata.',
 		'no_configure_view' => 'Questa estensioni non può essere configurata.',
 		'system' => array(
 		'system' => array(
 			'_' => 'Estensioni di sistema',
 			'_' => 'Estensioni di sistema',
 			'no_rights' => 'Estensione di sistema (non hai i permessi su questo tipo)',
 			'no_rights' => 'Estensione di sistema (non hai i permessi su questo tipo)',
 		),
 		),
 		'title' => 'Estensioni',
 		'title' => 'Estensioni',
+		'update' => 'Update available',	//TODO - Translation
 		'user' => 'Estensioni utente',
 		'user' => 'Estensioni utente',
-		'community' => 'Available community extensions', // @todo translate
-		'name' => 'Name', // @todo translate
-		'version' => 'Version', // @todo translate
-		'description' => 'Description', // @todo translate
-		'author' => 'Author', // @todo translate
-		'latest' => 'Installed', // @todo translate
-		'update' => 'Update available', // @todo translate
+		'version' => 'Version',	//TODO - Translation
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistiche',
 		'_' => 'Statistiche',
@@ -158,10 +158,14 @@ return array(
 	),
 	),
 	'system' => array(
 	'system' => array(
 		'_' => 'Configurazione di sistema',
 		'_' => 'Configurazione di sistema',
-		'auto-update-url' => 'Auto-update server URL', // @todo translate
+		'auto-update-url' => 'Auto-update server URL',	//TODO - Translation
 		'instance-name' => 'Nome istanza',
 		'instance-name' => 'Nome istanza',
 		'max-categories' => 'Limite categorie per utente',
 		'max-categories' => 'Limite categorie per utente',
 		'max-feeds' => 'Limite feeds per utente',
 		'max-feeds' => 'Limite feeds per utente',
+		'cookie-duration' => array(
+			'help' => 'in seconds', // @todo translate
+			'number' => 'Duration to keep logged in', // @todo translate
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 significa che non esiste limite sui profili',
 			'help' => '0 significa che non esiste limite sui profili',
 			'number' => 'Numero massimo di profili',
 			'number' => 'Numero massimo di profili',
@@ -179,15 +183,15 @@ return array(
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s articoli (%s)',
 		'articles_and_size' => '%s articoli (%s)',
 		'create' => 'Crea nuovo utente',
 		'create' => 'Crea nuovo utente',
-		'delete_users' => 'Delete user', // TODO
+		'delete_users' => 'Delete user',	//TODO - Translation
 		'language' => 'Lingua',
 		'language' => 'Lingua',
 		'number' => ' %d profilo utente creato',
 		'number' => ' %d profilo utente creato',
 		'numbers' => 'Sono presenti %d profili utente',
 		'numbers' => 'Sono presenti %d profili utente',
 		'password_form' => 'Password<br /><small>(per il login classico)</small>',
 		'password_form' => 'Password<br /><small>(per il login classico)</small>',
 		'password_format' => 'Almeno 7 caratteri',
 		'password_format' => 'Almeno 7 caratteri',
-		'selected' => 'Selected user', // TODO
+		'selected' => 'Selected user',	//TODO - Translation
 		'title' => 'Gestione utenti',
 		'title' => 'Gestione utenti',
-		'update_users' => 'Update user', // TODO
+		'update_users' => 'Update user',	//TODO - Translation
 		'user_list' => 'Lista utenti',
 		'user_list' => 'Lista utenti',
 		'username' => 'Nome utente',
 		'username' => 'Nome utente',
 		'users' => 'Utenti',
 		'users' => 'Utenti',

+ 27 - 24
app/i18n/it/conf.php

@@ -19,7 +19,7 @@ return array(
 			'bottom_line' => 'Barra in fondo',
 			'bottom_line' => 'Barra in fondo',
 			'entry' => 'Icone degli articoli',
 			'entry' => 'Icone degli articoli',
 			'publication_date' => 'Data di pubblicazione',
 			'publication_date' => 'Data di pubblicazione',
-			'related_tags' => 'Tags correlati',	//TODO
+			'related_tags' => 'Tags correlati',	//TODO - Translation
 			'sharing' => 'Condivisione',
 			'sharing' => 'Condivisione',
 			'top_line' => 'Barra in alto',
 			'top_line' => 'Barra in alto',
 		),
 		),
@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'secondi (0 significa nessun timeout)',
 			'seconds' => 'secondi (0 significa nessun timeout)',
 			'timeout' => 'Notifica timeout HTML5',
 			'timeout' => 'Notifica timeout HTML5',
 		),
 		),
+		'show_nav_buttons' => 'Show the navigation buttons',	//TODO - Translation
 		'theme' => 'Tema',
 		'theme' => 'Tema',
 		'title' => 'Visualizzazione',
 		'title' => 'Visualizzazione',
 		'width' => array(
 		'width' => array(
@@ -37,12 +38,22 @@ return array(
 			'no_limit' => 'Nessun limite',
 			'no_limit' => 'Nessun limite',
 			'thin' => 'Stretto',
 			'thin' => 'Stretto',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	//TODO
+	),
+	'profile' => array(
+		'_' => 'Gestione profili',
+		'delete' => array(
+			'_' => 'Cancellazione account',
+			'warn' => 'Il tuo account e tutti i dati associati saranno cancellati.',
+		),
+		'password_api' => 'Password API<br /><small>(e.g., per applicazioni mobili)</small>',
+		'password_form' => 'Password<br /><small>(per il login classico)</small>',
+		'password_format' => 'Almeno 7 caratteri',
+		'title' => 'Profilo',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'Ricerche personali',
 		'_' => 'Ricerche personali',
 		'deprecated' => 'Questa query non è più valida. La categoria o il feed di riferimento non stati cancellati.',
 		'deprecated' => 'Questa query non è più valida. La categoria o il feed di riferimento non stati cancellati.',
-		'display' => 'Display user query results', // TODO
+		'display' => 'Display user query results',	//TODO - Translation
 		'filter' => 'Filtro applicato:',
 		'filter' => 'Filtro applicato:',
 		'get_all' => 'Mostra tutti gli articoli',
 		'get_all' => 'Mostra tutti gli articoli',
 		'get_category' => 'Mostra la categoria "%s" ',
 		'get_category' => 'Mostra la categoria "%s" ',
@@ -53,7 +64,7 @@ return array(
 		'number' => 'Ricerca n°%d',
 		'number' => 'Ricerca n°%d',
 		'order_asc' => 'Mostra prima gli articoli più vecchi',
 		'order_asc' => 'Mostra prima gli articoli più vecchi',
 		'order_desc' => 'Mostra prima gli articoli più nuovi',
 		'order_desc' => 'Mostra prima gli articoli più nuovi',
-		'remove' => 'Remove user query', // TODO
+		'remove' => 'Remove user query',	//TODO - Translation
 		'search' => 'Cerca per "%s"',
 		'search' => 'Cerca per "%s"',
 		'state_0' => 'Mostra tutti gli articoli',
 		'state_0' => 'Mostra tutti gli articoli',
 		'state_1' => 'Mostra gli articoli letti',
 		'state_1' => 'Mostra gli articoli letti',
@@ -73,31 +84,19 @@ return array(
 		'state_15' => 'Mostra tutti gli articoli',
 		'state_15' => 'Mostra tutti gli articoli',
 		'title' => 'Ricerche personali',
 		'title' => 'Ricerche personali',
 	),
 	),
-	'profile' => array(
-		'_' => 'Gestione profili',
-		'delete' => array(
-			'_' => 'Cancellazione account',
-			'warn' => 'Il tuo account e tutti i dati associati saranno cancellati.',
-		),
-		'password_api' => 'Password API<br /><small>(e.g., per applicazioni mobili)</small>',
-		'password_form' => 'Password<br /><small>(per il login classico)</small>',
-		'password_format' => 'Almeno 7 caratteri',
-		'title' => 'Profilo',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Lettura',
 		'_' => 'Lettura',
 		'after_onread' => 'Dopo “segna tutto come letto”,',
 		'after_onread' => 'Dopo “segna tutto come letto”,',
 		'articles_per_page' => 'Numero di articoli per pagina',
 		'articles_per_page' => 'Numero di articoli per pagina',
 		'auto_load_more' => 'Carica articoli successivi a fondo pagina',
 		'auto_load_more' => 'Carica articoli successivi a fondo pagina',
 		'auto_remove_article' => 'Nascondi articoli dopo la lettura',
 		'auto_remove_article' => 'Nascondi articoli dopo la lettura',
-		'mark_updated_article_unread' => 'Segna articoli aggiornati come non letti',
 		'confirm_enabled' => 'Mostra una conferma per “segna tutto come letto”',
 		'confirm_enabled' => 'Mostra una conferma per “segna tutto come letto”',
 		'display_articles_unfolded' => 'Mostra articoli aperti di predefinito',
 		'display_articles_unfolded' => 'Mostra articoli aperti di predefinito',
 		'display_categories_unfolded' => 'Mostra categorie aperte di predefinito',
 		'display_categories_unfolded' => 'Mostra categorie aperte di predefinito',
 		'hide_read_feeds' => 'Nascondi categorie e feeds con articoli già letti (non funziona se “Mostra tutti gli articoli” è selezionato)',
 		'hide_read_feeds' => 'Nascondi categorie e feeds con articoli già letti (non funziona se “Mostra tutti gli articoli” è selezionato)',
 		'img_with_lazyload' => 'Usa la modalità "caricamento ritardato" per le immagini',
 		'img_with_lazyload' => 'Usa la modalità "caricamento ritardato" per le immagini',
-		'sides_close_article' => 'Clicking outside of article text area closes the article',	//TODO
 		'jump_next' => 'Salta al successivo feed o categoria non letto',
 		'jump_next' => 'Salta al successivo feed o categoria non letto',
+		'mark_updated_article_unread' => 'Segna articoli aggiornati come non letti',
 		'number_divided_when_reader' => 'Diviso 2 nella modalità di lettura.',
 		'number_divided_when_reader' => 'Diviso 2 nella modalità di lettura.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'Quando un articolo è aperto nel suo sito di origine',
 			'article_open_on_website' => 'Quando un articolo è aperto nel suo sito di origine',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => 'Mostra tutti gli articoli',
 			'all_articles' => 'Mostra tutti gli articoli',
 			'unread' => 'Mostra solo non letti',
 			'unread' => 'Mostra solo non letti',
 		),
 		),
+		'sides_close_article' => 'Clicking outside of article text area closes the article',	//TODO - Translation
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Ordinamento',
 			'_' => 'Ordinamento',
 			'newer_first' => 'Prima i più recenti',
 			'newer_first' => 'Prima i più recenti',
@@ -128,7 +128,7 @@ return array(
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Condivisione',
 		'_' => 'Condivisione',
-		'add' => 'Add a sharing method', // TODO
+		'add' => 'Add a sharing method',	//TODO - Translation
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -136,7 +136,7 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'more_information' => 'Ulteriori informazioni',
 		'more_information' => 'Ulteriori informazioni',
 		'print' => 'Stampa',
 		'print' => 'Stampa',
-		'remove' => 'Remove sharing method', // TODO
+		'remove' => 'Remove sharing method',	//TODO - Translation
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
 		'share_name' => 'Nome condivisione',
 		'share_name' => 'Nome condivisione',
 		'share_url' => 'URL condivisione',
 		'share_url' => 'URL condivisione',
@@ -153,27 +153,30 @@ return array(
 		'collapse_article' => 'Collassa articoli',
 		'collapse_article' => 'Collassa articoli',
 		'first_article' => 'Salta al primo articolo',
 		'first_article' => 'Salta al primo articolo',
 		'focus_search' => 'Modulo di ricerca',
 		'focus_search' => 'Modulo di ricerca',
-		'global_view' => 'Switch to global view', // TODO
+		'global_view' => 'Switch to global view',	//TODO - Translation
 		'help' => 'Mostra documentazione',
 		'help' => 'Mostra documentazione',
 		'javascript' => 'JavaScript deve essere abilitato per poter usare i comandi da tastiera',
 		'javascript' => 'JavaScript deve essere abilitato per poter usare i comandi da tastiera',
 		'last_article' => 'Salta all ultimo articolo',
 		'last_article' => 'Salta all ultimo articolo',
 		'load_more' => 'Carica altri articoli',
 		'load_more' => 'Carica altri articoli',
-		'mark_read' => 'Segna come letto',
 		'mark_favorite' => 'Segna come preferito',
 		'mark_favorite' => 'Segna come preferito',
+		'mark_read' => 'Segna come letto',
 		'navigation' => 'Navigazione',
 		'navigation' => 'Navigazione',
 		'navigation_help' => 'Con il tasto "Shift" i comandi di navigazione verranno applicati ai feeds.<br/>Con il tasto "Alt" i comandi di navigazione verranno applicati alle categorie.',
 		'navigation_help' => 'Con il tasto "Shift" i comandi di navigazione verranno applicati ai feeds.<br/>Con il tasto "Alt" i comandi di navigazione verranno applicati alle categorie.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => 'Salta al contenuto successivo',
 		'next_article' => 'Salta al contenuto successivo',
 		'normal_view' => 'Switch to normal view', // TODO
 		'normal_view' => 'Switch to normal view', // TODO
 		'other_action' => 'Altre azioni',
 		'other_action' => 'Altre azioni',
 		'previous_article' => 'Salta al contenuto precedente',
 		'previous_article' => 'Salta al contenuto precedente',
-		'reading_view' => 'Switch to reading view', // TODO
-		'rss_view' => 'Open RSS view in a new tab', // TODO
+		'reading_view' => 'Switch to reading view',	//TODO - Translation
+		'rss_view' => 'Open RSS view in a new tab',	//TODO - Translation
 		'see_on_website' => 'Vai al sito fonte',
 		'see_on_website' => 'Vai al sito fonte',
 		'shift_for_all_read' => '+ <code>shift</code> per segnare tutti gli articoli come letti',
 		'shift_for_all_read' => '+ <code>shift</code> per segnare tutti gli articoli come letti',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => 'Comandi da tastiera',
 		'title' => 'Comandi da tastiera',
 		'user_filter' => 'Accedi alle ricerche personali',
 		'user_filter' => 'Accedi alle ricerche personali',
 		'user_filter_help' => 'Se è presente una sola ricerca personale verrà usata quella, altrimenti usare anche il numero associato.',
 		'user_filter_help' => 'Se è presente una sola ricerca personale verrà usata quella, altrimenti usare anche il numero associato.',
-		'views' => 'Views', // TODO
+		'views' => 'Views',	//TODO - Translation
 	),
 	),
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s articoli (%s)',
 		'articles_and_size' => '%s articoli (%s)',

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

@@ -50,11 +50,15 @@ return array(
 		'no_zip_extension' => 'Estensione ZIP non presente sul server.',
 		'no_zip_extension' => 'Estensione ZIP non presente sul server.',
 		'zip_error' => 'Si è verificato un errore importando il file ZIP',
 		'zip_error' => 'Si è verificato un errore importando il file ZIP',
 	),
 	),
+	'profile' => array(
+		'error' => 'Il tuo profilo non può essere modificato',
+		'updated' => 'Il tuo profilo è stato modificato',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Aggiorna',
 		'actualize' => 'Aggiorna',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	//TODO
-			'marked_unread' => 'The articles have been marked as unread.',	//TODO
+			'marked_read' => 'The selected articles have been marked as read.',	//TODO - Translation
+			'marked_unread' => 'The articles have been marked as unread.',	//TODO - Translation
 		),
 		),
 		'category' => array(
 		'category' => array(
 			'created' => 'Categoria %s creata.',
 			'created' => 'Categoria %s creata.',
@@ -76,7 +80,7 @@ return array(
 			'already_subscribed' => 'Hai già sottoscritto <em>%s</em>',
 			'already_subscribed' => 'Hai già sottoscritto <em>%s</em>',
 			'deleted' => 'Feed cancellato',
 			'deleted' => 'Feed cancellato',
 			'error' => 'Feed non aggiornato',
 			'error' => 'Feed non aggiornato',
-			'internal_problem' => 'RSS feed non aggiunto. <a href="%s">Verifica i logs</a> per dettagli.', // @todo
+			'internal_problem' => 'RSS feed non aggiunto. <a href="%s">Verifica i logs</a> per dettagli.',	//TODO - Translation
 			'invalid_url' => 'URL <em>%s</em> non valido',
 			'invalid_url' => 'URL <em>%s</em> non valido',
 			'n_actualized' => '%d feeds aggiornati',
 			'n_actualized' => '%d feeds aggiornati',
 			'n_entries_deleted' => '%d articoli cancellati',
 			'n_entries_deleted' => '%d articoli cancellati',
@@ -105,12 +109,8 @@ return array(
 			'error' => 'Utente %s non cancellato',
 			'error' => 'Utente %s non cancellato',
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated', // TODO
-			'error' => 'User %s has not been updated', // TODO
+			'_' => 'User %s has been updated',	//TODO - Translation
+			'error' => 'User %s has not been updated',	//TODO - Translation
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => 'Il tuo profilo non può essere modificato',
-		'updated' => 'Il tuo profilo è stato modificato',
-	),
 );
 );

+ 14 - 12
app/i18n/it/gen.php

@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\A\\p\\r\\i\\l\\e',
 		'Apr' => '\\A\\p\\r\\i\\l\\e',
-		'Aug' => '\\A\\g\\o\\s\\t\\o',
-		'Dec' => '\\D\\i\\c\\e\\m\\b\\r\\e',
-		'Feb' => '\\F\\e\\b\\b\\r\\a\\i\\o',
-		'Jan' => '\\G\\e\\n\\u\\a\\i\\o',
-		'Jul' => '\\L\\u\\g\\l\\i\\o',
-		'Jun' => '\\G\\i\\u\\g\\n\\o',
-		'Mar' => '\\M\\a\\r\\z\\o',
-		'May' => '\\M\\a\\g\\g\\i\\o',
-		'Nov' => '\\N\\o\\v\\e\\m\\b\\r\\e',
-		'Oct' => '\\O\\t\\t\\o\\b\\r\\e',
-		'Sep' => '\\S\\e\\t\\t\\e\\m\\b\\r\\e',
 		'apr' => 'apr.',
 		'apr' => 'apr.',
 		'april' => 'aprile',
 		'april' => 'aprile',
+		'Aug' => '\\A\\g\\o\\s\\t\\o',
 		'aug' => 'ag.',
 		'aug' => 'ag.',
 		'august' => 'agosto',
 		'august' => 'agosto',
 		'before_yesterday' => 'Meno recenti',
 		'before_yesterday' => 'Meno recenti',
+		'Dec' => '\\D\\i\\c\\e\\m\\b\\r\\e',
 		'dec' => 'dic.',
 		'dec' => 'dic.',
 		'december' => 'dicembre',
 		'december' => 'dicembre',
+		'Feb' => '\\F\\e\\b\\b\\r\\a\\i\\o',
 		'feb' => 'febbr.',
 		'feb' => 'febbr.',
 		'february' => 'febbraio',
 		'february' => 'febbraio',
 		'format_date' => 'j\\ %s Y',
 		'format_date' => 'j\\ %s Y',
 		'format_date_hour' => 'j\\ %s Y \\o\\r\\e H\\:i',
 		'format_date_hour' => 'j\\ %s Y \\o\\r\\e H\\:i',
 		'fri' => 'Fri',
 		'fri' => 'Fri',
+		'Jan' => '\\G\\e\\n\\u\\a\\i\\o',
 		'jan' => 'genn.',
 		'jan' => 'genn.',
 		'january' => 'gennaio',
 		'january' => 'gennaio',
+		'Jul' => '\\L\\u\\g\\l\\i\\o',
 		'jul' => 'jul',
 		'jul' => 'jul',
 		'july' => 'luglio',
 		'july' => 'luglio',
+		'Jun' => '\\G\\i\\u\\g\\n\\o',
 		'jun' => 'jun',
 		'jun' => 'jun',
 		'june' => 'giugno',
 		'june' => 'giugno',
 		'last_3_month' => 'Ultimi 3 mesi',
 		'last_3_month' => 'Ultimi 3 mesi',
@@ -78,17 +73,22 @@ return array(
 		'last_month' => 'Ultimo mese',
 		'last_month' => 'Ultimo mese',
 		'last_week' => 'Ultima settimana',
 		'last_week' => 'Ultima settimana',
 		'last_year' => 'Ultimo anno',
 		'last_year' => 'Ultimo anno',
+		'Mar' => '\\M\\a\\r\\z\\o',
 		'mar' => 'mar.',
 		'mar' => 'mar.',
 		'march' => 'marzo',
 		'march' => 'marzo',
+		'May' => '\\M\\a\\g\\g\\i\\o',
 		'may' => 'maggio',
 		'may' => 'maggio',
 		'may_' => 'May',
 		'may_' => 'May',
 		'mon' => 'Mon',
 		'mon' => 'Mon',
 		'month' => 'mesi',
 		'month' => 'mesi',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\r\\e',
 		'nov' => 'nov.',
 		'nov' => 'nov.',
 		'november' => 'novembre',
 		'november' => 'novembre',
+		'Oct' => '\\O\\t\\t\\o\\b\\r\\e',
 		'oct' => 'ott.',
 		'oct' => 'ott.',
 		'october' => 'ottobre',
 		'october' => 'ottobre',
 		'sat' => 'Sat',
 		'sat' => 'Sat',
+		'Sep' => '\\S\\e\\t\\t\\e\\m\\b\\r\\e',
 		'sep' => 'sett.',
 		'sep' => 'sett.',
 		'september' => 'settembre',
 		'september' => 'settembre',
 		'sun' => 'Sun',
 		'sun' => 'Sun',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -160,7 +161,6 @@ return array(
 		'previous' => 'Precedente',
 		'previous' => 'Precedente',
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Siti basati su Known',
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -168,9 +168,11 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'gnusocial' => 'GNU social',
 		'gnusocial' => 'GNU social',
 		'jdh' => 'Journal du hacker',
 		'jdh' => 'Journal du hacker',
+		'Known' => 'Siti basati su Known',
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Stampa',
 		'print' => 'Stampa',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',

+ 3 - 3
app/i18n/it/index.php

@@ -40,7 +40,7 @@ return array(
 		'mark_all_read' => 'Segna tutto come letto',
 		'mark_all_read' => 'Segna tutto come letto',
 		'mark_cat_read' => 'Segna la categoria come letta',
 		'mark_cat_read' => 'Segna la categoria come letta',
 		'mark_feed_read' => 'Segna il feed come letto',
 		'mark_feed_read' => 'Segna il feed come letto',
-		'mark_selection_unread' => 'Mark selection as unread',	//TODO
+		'mark_selection_unread' => 'Mark selection as unread',	//TODO - Translation
 		'newer_first' => 'Mostra prima i recenti',
 		'newer_first' => 'Mostra prima i recenti',
 		'non-starred' => 'Escludi preferiti',
 		'non-starred' => 'Escludi preferiti',
 		'normal_view' => 'Vista elenco',
 		'normal_view' => 'Vista elenco',
@@ -53,11 +53,11 @@ return array(
 		'starred' => 'Mostra solo preferiti',
 		'starred' => 'Mostra solo preferiti',
 		'stats' => 'Statistiche',
 		'stats' => 'Statistiche',
 		'subscription' => 'Gestione sottoscrizioni',
 		'subscription' => 'Gestione sottoscrizioni',
-		'tags' => 'My labels',	//TODO
+		'tags' => 'My labels',	//TODO - Translation
 		'unread' => 'Mostra solo non letti',
 		'unread' => 'Mostra solo non letti',
 	),
 	),
 	'share' => 'Condividi',
 	'share' => 'Condividi',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Tags correlati',	//TODO
+		'related' => 'Tags correlati',	//TODO - Translation
 	),
 	),
 );
 );

+ 3 - 4
app/i18n/it/install.php

@@ -24,8 +24,8 @@ return array(
 			'ok' => 'Le configurazioni del database sono state salvate.',
 			'ok' => 'Le configurazioni del database sono state salvate.',
 		),
 		),
 		'host' => 'Host',
 		'host' => 'Host',
-		'prefix' => 'Prefisso tabella',
 		'password' => 'Password del database',
 		'password' => 'Password del database',
+		'prefix' => 'Prefisso tabella',
 		'type' => 'Tipo di database',
 		'type' => 'Tipo di database',
 		'username' => 'Nome utente del database',
 		'username' => 'Nome utente del database',
 	),
 	),
@@ -69,8 +69,8 @@ return array(
 			'ok' => 'You have a recommended library to parse JSON.',
 			'ok' => 'You have a recommended library to parse JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Manca il framework Minz.',
 			'nok' => 'Manca il framework Minz.',
@@ -85,7 +85,6 @@ return array(
 			'ok' => 'PDO e altri driver supportati (pdo_mysql, pdo_sqlite, pdo_pgsql).',
 			'ok' => 'PDO e altri driver supportati (pdo_mysql, pdo_sqlite, pdo_pgsql).',
 		),
 		),
 		'php' => array(
 		'php' => array(
-			'_' => 'Installazione PHP',
 			'nok' => 'Versione di PHP %s FreshRSS richiede almeno la versione %s.',
 			'nok' => 'Versione di PHP %s FreshRSS richiede almeno la versione %s.',
 			'ok' => 'Versione di PHP %s, compatibile con FreshRSS.',
 			'ok' => 'Versione di PHP %s, compatibile con FreshRSS.',
 		),
 		),

+ 24 - 17
app/i18n/it/sub.php

@@ -2,13 +2,13 @@
 
 
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',// TODO
-		'title' => 'API',// TODO
+		'documentation' => 'Copy the following URL to use it within an external tool.',	//TODO - Translation
+		'title' => 'API',	//TODO - Translation
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
 		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',// TODO
 		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',// TODO
-		'label' => 'Subscribe',// TODO
-		'title' => 'Bookmarklet',// TODO
+		'label' => 'Subscribe',	//TODO - Translation
+		'title' => 'Bookmarklet',	//TODO - Translation
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Categoria',
 		'_' => 'Categoria',
@@ -27,7 +27,7 @@ return array(
 			'password' => 'HTTP password',
 			'password' => 'HTTP password',
 			'username' => 'HTTP username',
 			'username' => 'HTTP username',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	//TODO
+		'clear_cache' => 'Always clear cache',	//TODO - Translation
 		'css_help' => 'In caso di RSS feeds troncati (attenzione, richiede molto tempo!)',
 		'css_help' => 'In caso di RSS feeds troncati (attenzione, richiede molto tempo!)',
 		'css_path' => 'Percorso del foglio di stile CSS del sito di origine',
 		'css_path' => 'Percorso del foglio di stile CSS del sito di origine',
 		'description' => 'Descrizione',
 		'description' => 'Descrizione',
@@ -36,30 +36,37 @@ return array(
 		'informations' => 'Informazioni',
 		'informations' => 'Informazioni',
 		'keep_history' => 'Numero minimo di articoli da mantenere',
 		'keep_history' => 'Numero minimo di articoli da mantenere',
 		'moved_category_deleted' => 'Cancellando una categoria i feed al suo interno verranno classificati automaticamente come <em>%s</em>.',
 		'moved_category_deleted' => 'Cancellando una categoria i feed al suo interno verranno classificati automaticamente come <em>%s</em>.',
-		'mute' => 'mute', // TODO
+		'mute' => 'mute',	//TODO - Translation
 		'no_selected' => 'Nessun feed selezionato.',
 		'no_selected' => 'Nessun feed selezionato.',
 		'number_entries' => '%d articoli',
 		'number_entries' => '%d articoli',
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility', // TODO
-			'archived' => 'Do not show (archived)', // TODO
-			'main_stream' => 'Mostra in homepage', // TODO
-			'normal' => 'Show in its category', // TODO
+			'_' => 'Visibility',	//TODO - Translation
+			'archived' => 'Do not show (archived)',	//TODO - Translation
+			'main_stream' => 'Mostra in homepage',	//TODO - Translation
+			'normal' => 'Show in its category',	//TODO - Translation
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	//TODO
+		'websub' => 'Notifica istantanea con WebSub',
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
+		'ssl_verify' => 'Verify SSL security',	//TODO - Translation
 		'stats' => 'Statistiche',
 		'stats' => 'Statistiche',
 		'think_to_add' => 'Aggiungi feed.',
 		'think_to_add' => 'Aggiungi feed.',
-		'timeout' => 'Timeout in seconds',	//TODO
+		'timeout' => 'Timeout in seconds',	//TODO - Translation
 		'title' => 'Titolo',
 		'title' => 'Titolo',
 		'title_add' => 'Aggiungi RSS feed',
 		'title_add' => 'Aggiungi RSS feed',
 		'ttl' => 'Non aggiornare automaticamente piu di',
 		'ttl' => 'Non aggiornare automaticamente piu di',
 		'url' => 'Feed URL',
 		'url' => 'Feed URL',
 		'validator' => 'Controlla la validita del feed ',
 		'validator' => 'Controlla la validita del feed ',
 		'website' => 'URL del sito',
 		'website' => 'URL del sito',
-		'pubsubhubbub' => 'Notifica istantanea con PubSubHubbub',
 	),
 	),
 	'firefox' => array(
 	'firefox' => array(
-		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',// TODO
-		'title' => 'Firefox feed reader',// TODO
+		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',	//TODO - Translation
+		'title' => 'Firefox feed reader',	//TODO - Translation
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export' => 'Esporta',
 		'export' => 'Esporta',
@@ -76,11 +83,11 @@ return array(
 		'bookmark' => 'Bookmark (trascina nei preferiti)',
 		'bookmark' => 'Bookmark (trascina nei preferiti)',
 		'import_export' => 'Importa / esporta',
 		'import_export' => 'Importa / esporta',
 		'subscription_management' => 'Gestione sottoscrizioni',
 		'subscription_management' => 'Gestione sottoscrizioni',
-		'subscription_tools' => 'Subscription tools',// TODO
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 	'title' => array(
 	'title' => array(
 		'_' => 'Gestione sottoscrizioni',
 		'_' => 'Gestione sottoscrizioni',
 		'feed_management' => 'Gestione RSS feeds',
 		'feed_management' => 'Gestione RSS feeds',
-		'subscription_tools' => 'Subscription tools',// TODO
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 );
 );

+ 12 - 8
app/i18n/kr/admin.php

@@ -67,8 +67,8 @@ return array(
 			'ok' => 'JSON  확장 기능이 설치되어 있습니다.',
 			'ok' => 'JSON  확장 기능이 설치되어 있습니다.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Minz 프레임워크를 찾을 수 없습니다.',
 			'nok' => 'Minz 프레임워크를 찾을 수 없습니다.',
@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => '제작자',
+		'community' => '사용 가능한 커뮤니티 확장 기능들',
+		'description' => '설명',
 		'disabled' => '비활성화됨',
 		'disabled' => '비활성화됨',
 		'empty_list' => '설치된 확장 기능이 없습니다',
 		'empty_list' => '설치된 확장 기능이 없습니다',
 		'enabled' => '활성화됨',
 		'enabled' => '활성화됨',
+		'latest' => '설치됨',
+		'name' => '이름',
 		'no_configure_view' => '이 확장 기능은 설정이 없습니다.',
 		'no_configure_view' => '이 확장 기능은 설정이 없습니다.',
 		'system' => array(
 		'system' => array(
 			'_' => '시스템 확장 기능',
 			'_' => '시스템 확장 기능',
 			'no_rights' => '시스템 확장 기능 (이 확장 기능에 대한 권한이 없습니다)',
 			'no_rights' => '시스템 확장 기능 (이 확장 기능에 대한 권한이 없습니다)',
 		),
 		),
 		'title' => '확장 기능',
 		'title' => '확장 기능',
+		'update' => '업데이트 있음',
 		'user' => '사용자 확장 기능',
 		'user' => '사용자 확장 기능',
-		'community' => '사용 가능한 커뮤니티 확장 기능들',
-		'name' => '이름',
 		'version' => '버전',
 		'version' => '버전',
-		'description' => '설명',
-		'author' => '제작자',
-		'latest' => '설치됨',
-		'update' => '업데이트 있음',
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => '통계',
 		'_' => '통계',
@@ -162,6 +162,10 @@ return array(
 		'instance-name' => '인스턴스 이름',
 		'instance-name' => '인스턴스 이름',
 		'max-categories' => '사용자별 카테고리 개수 제한',
 		'max-categories' => '사용자별 카테고리 개수 제한',
 		'max-feeds' => '사용자별 피드 개수 제한',
 		'max-feeds' => '사용자별 피드 개수 제한',
+		'cookie-duration' => array(
+			'help' => 'in seconds', // @todo translate
+			'number' => 'Duration to keep logged in', // @todo translate
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => '0: 제한 없음',
 			'help' => '0: 제한 없음',
 			'number' => '계정 최대 개수',
 			'number' => '계정 최대 개수',

+ 19 - 16
app/i18n/kr/conf.php

@@ -19,7 +19,7 @@ return array(
 			'bottom_line' => '하단',
 			'bottom_line' => '하단',
 			'entry' => '문서 아이콘',
 			'entry' => '문서 아이콘',
 			'publication_date' => '발행일',
 			'publication_date' => '발행일',
-			'related_tags' => '관련 태그',	//TODO
+			'related_tags' => '관련 태그',
 			'sharing' => '공유',
 			'sharing' => '공유',
 			'top_line' => '상단',
 			'top_line' => '상단',
 		),
 		),
@@ -28,6 +28,7 @@ return array(
 			'seconds' => '초 (0: 타임아웃 없음)',
 			'seconds' => '초 (0: 타임아웃 없음)',
 			'timeout' => 'HTML5 알림 타임아웃',
 			'timeout' => 'HTML5 알림 타임아웃',
 		),
 		),
+		'show_nav_buttons' => '내비게이션 버튼 보이기',
 		'theme' => '테마',
 		'theme' => '테마',
 		'title' => '표시',
 		'title' => '표시',
 		'width' => array(
 		'width' => array(
@@ -37,7 +38,17 @@ return array(
 			'no_limit' => '제한 없음',
 			'no_limit' => '제한 없음',
 			'thin' => '얇음',
 			'thin' => '얇음',
 		),
 		),
-		'show_nav_buttons' => '내비게이션 버튼 보이기',
+	),
+	'profile' => array(
+		'_' => '프로필 관리',
+		'delete' => array(
+			'_' => '계정 삭제',
+			'warn' => '당신의 계정과 관련된 모든 데이터가 삭제됩니다.',
+		),
+		'password_api' => 'API 암호<br /><small>(예: 모바일 애플리케이션)</small>',
+		'password_form' => '암호<br /><small>(웹폼 로그인 방식 사용시)</small>',
+		'password_format' => '7 글자 이상이어야 합니다',
+		'title' => '프로필',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => '사용자 쿼리',
 		'_' => '사용자 쿼리',
@@ -73,31 +84,19 @@ return array(
 		'state_15' => '모든 글 표시',
 		'state_15' => '모든 글 표시',
 		'title' => '사용자 쿼리',
 		'title' => '사용자 쿼리',
 	),
 	),
-	'profile' => array(
-		'_' => '프로필 관리',
-		'delete' => array(
-			'_' => '계정 삭제',
-			'warn' => '당신의 계정과 관련된 모든 데이터가 삭제됩니다.',
-		),
-		'password_api' => 'API 암호<br /><small>(예: 모바일 애플리케이션)</small>',
-		'password_form' => '암호<br /><small>(웹폼 로그인 방식 사용시)</small>',
-		'password_format' => '7 글자 이상이어야 합니다',
-		'title' => '프로필',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => '읽기',
 		'_' => '읽기',
 		'after_onread' => '“모두 읽음으로 표시” 후,',
 		'after_onread' => '“모두 읽음으로 표시” 후,',
 		'articles_per_page' => '페이지당 글 수',
 		'articles_per_page' => '페이지당 글 수',
 		'auto_load_more' => '페이지 하단에 다다르면 글 더 불러오기',
 		'auto_load_more' => '페이지 하단에 다다르면 글 더 불러오기',
 		'auto_remove_article' => '글을 읽은 후 숨기기',
 		'auto_remove_article' => '글을 읽은 후 숨기기',
-		'mark_updated_article_unread' => '갱신 된 글을 읽지 않음으로 표시',
 		'confirm_enabled' => '“모두 읽음으로 표시” 실행시 확인 창 표시',
 		'confirm_enabled' => '“모두 읽음으로 표시” 실행시 확인 창 표시',
 		'display_articles_unfolded' => '글을 펼쳐진 상태로 보여주기',
 		'display_articles_unfolded' => '글을 펼쳐진 상태로 보여주기',
 		'display_categories_unfolded' => '카테고리를 접힌 상태로 보여주기',
 		'display_categories_unfolded' => '카테고리를 접힌 상태로 보여주기',
 		'hide_read_feeds' => '읽지 않은 글이 없는 카테고리와 피드 감추기 (“모든 글 표시”가 설정된 경우 동작하지 않습니다)',
 		'hide_read_feeds' => '읽지 않은 글이 없는 카테고리와 피드 감추기 (“모든 글 표시”가 설정된 경우 동작하지 않습니다)',
 		'img_with_lazyload' => '그림을 불러오는 데에 "lazy load" 모드 사용하기',
 		'img_with_lazyload' => '그림을 불러오는 데에 "lazy load" 모드 사용하기',
-		'sides_close_article' => '글 영역 바깥을 클릭하면 글 접기',
 		'jump_next' => '다음 읽지 않은 항목으로 이동 (피드 또는 카테고리)',
 		'jump_next' => '다음 읽지 않은 항목으로 이동 (피드 또는 카테고리)',
+		'mark_updated_article_unread' => '갱신 된 글을 읽지 않음으로 표시',
 		'number_divided_when_reader' => '읽기 모드에서는 절반만 표시됩니다.',
 		'number_divided_when_reader' => '읽기 모드에서는 절반만 표시됩니다.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => '글이 게재된 웹사이트를 방문했을 때',
 			'article_open_on_website' => '글이 게재된 웹사이트를 방문했을 때',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => '모든 글 표시',
 			'all_articles' => '모든 글 표시',
 			'unread' => '읽지 않은 글만 표시',
 			'unread' => '읽지 않은 글만 표시',
 		),
 		),
+		'sides_close_article' => '글 영역 바깥을 클릭하면 글 접기',
 		'sort' => array(
 		'sort' => array(
 			'_' => '정렬 순서',
 			'_' => '정렬 순서',
 			'newer_first' => '최근 글 먼저',
 			'newer_first' => '최근 글 먼저',
@@ -158,10 +158,11 @@ return array(
 		'javascript' => '단축키를 사용하기 위해선 자바스크립트를 사용하도록 설정하여야 합니다',
 		'javascript' => '단축키를 사용하기 위해선 자바스크립트를 사용하도록 설정하여야 합니다',
 		'last_article' => '마지막 글 보기',
 		'last_article' => '마지막 글 보기',
 		'load_more' => '글 더 불러오기',
 		'load_more' => '글 더 불러오기',
-		'mark_read' => '읽음으로 표시',
 		'mark_favorite' => '즐겨찾기에 등록',
 		'mark_favorite' => '즐겨찾기에 등록',
+		'mark_read' => '읽음으로 표시',
 		'navigation' => '탐색',
 		'navigation' => '탐색',
 		'navigation_help' => '"Shift" 키를 누른 상태에선 탐색 단축키가 피드에 적용됩니다.<br/>"Alt" 키를 누른 상태에선 탐색 단축키가 카테고리에 적용됩니다.',
 		'navigation_help' => '"Shift" 키를 누른 상태에선 탐색 단축키가 피드에 적용됩니다.<br/>"Alt" 키를 누른 상태에선 탐색 단축키가 카테고리에 적용됩니다.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => '다음 글 보기',
 		'next_article' => '다음 글 보기',
 		'normal_view' => '일반 모드로 전환',
 		'normal_view' => '일반 모드로 전환',
 		'other_action' => '다른 동작',
 		'other_action' => '다른 동작',
@@ -170,6 +171,8 @@ return array(
 		'rss_view' => '새 탭에서 RSS 피드 열기',
 		'rss_view' => '새 탭에서 RSS 피드 열기',
 		'see_on_website' => '글이 게재된 웹사이트에서 보기',
 		'see_on_website' => '글이 게재된 웹사이트에서 보기',
 		'shift_for_all_read' => '+ <code>shift</code>를 누른 상태에선 모두 읽음으로 표시',
 		'shift_for_all_read' => '+ <code>shift</code>를 누른 상태에선 모두 읽음으로 표시',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => '단축키',
 		'title' => '단축키',
 		'user_filter' => '사용자 필터 사용하기',
 		'user_filter' => '사용자 필터 사용하기',
 		'user_filter_help' => '사용자 필터가 하나만 설정되어 있다면 해당 필터를 사용하고, 그렇지 않다면 필터를 번호로 선택할 수 있습니다.',
 		'user_filter_help' => '사용자 필터가 하나만 설정되어 있다면 해당 필터를 사용하고, 그렇지 않다면 필터를 번호로 선택할 수 있습니다.',

+ 6 - 6
app/i18n/kr/feedback.php

@@ -50,11 +50,15 @@ return array(
 		'no_zip_extension' => 'ZIP 확장 기능을 서버에서 찾을 수 없습니다.',
 		'no_zip_extension' => 'ZIP 확장 기능을 서버에서 찾을 수 없습니다.',
 		'zip_error' => 'ZIP 파일을 불러오는 동안 문제가 발생했습니다.',
 		'zip_error' => 'ZIP 파일을 불러오는 동안 문제가 발생했습니다.',
 	),
 	),
+	'profile' => array(
+		'error' => '프로필을 변경할 수 없습니다',
+		'updated' => '프로필을 변경했습니다',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => '피드를 가져오는 중입니다',
 		'actualize' => '피드를 가져오는 중입니다',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	//TODO
-			'marked_unread' => 'The articles have been marked as unread.',	//TODO
+			'marked_read' => 'The selected articles have been marked as read.',	//TODO - Translation
+			'marked_unread' => 'The articles have been marked as unread.',	//TODO - Translation
 		),
 		),
 		'category' => array(
 		'category' => array(
 			'created' => '%s 카테고리가 생성되었습니다.',
 			'created' => '%s 카테고리가 생성되었습니다.',
@@ -109,8 +113,4 @@ return array(
 			'error' => '사용자 %s의 정보가 변경되지 않았습니다',
 			'error' => '사용자 %s의 정보가 변경되지 않았습니다',
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => '프로필을 변경할 수 없습니다',
-		'updated' => '프로필을 변경했습니다',
-	),
 );
 );

+ 14 - 12
app/i18n/kr/gen.php

@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\A\\p\\r\\i\\l',
 		'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' => '4월',
 		'apr' => '4월',
 		'april' => '4월',
 		'april' => '4월',
+		'Aug' => '\\A\\u\\g\\u\\s\\t',
 		'aug' => '8월',
 		'aug' => '8월',
 		'august' => '8월',
 		'august' => '8월',
 		'before_yesterday' => '어제 이전',
 		'before_yesterday' => '어제 이전',
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
 		'dec' => '12월',
 		'dec' => '12월',
 		'december' => '12월',
 		'december' => '12월',
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',
 		'feb' => '2월',
 		'feb' => '2월',
 		'february' => '2월',
 		'february' => '2월',
 		'format_date' => 'Y년 m월 d일',
 		'format_date' => 'Y년 m월 d일',
 		'format_date_hour' => 'Y년 m월 d일 H시 i분',
 		'format_date_hour' => 'Y년 m월 d일 H시 i분',
 		'fri' => '금',
 		'fri' => '금',
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',
 		'jan' => '1월',
 		'jan' => '1월',
 		'january' => '1월',
 		'january' => '1월',
+		'Jul' => '\\J\\u\\l\\y',
 		'jul' => '7월',
 		'jul' => '7월',
 		'july' => '7월',
 		'july' => '7월',
+		'Jun' => '\\J\\u\\n\\e',
 		'jun' => '6월',
 		'jun' => '6월',
 		'june' => '6월',
 		'june' => '6월',
 		'last_3_month' => '최근 3 개월',
 		'last_3_month' => '최근 3 개월',
@@ -78,17 +73,22 @@ return array(
 		'last_month' => '최근 한 달',
 		'last_month' => '최근 한 달',
 		'last_week' => '최근 한 주',
 		'last_week' => '최근 한 주',
 		'last_year' => '최근 일 년',
 		'last_year' => '최근 일 년',
+		'Mar' => '\\M\\a\\r\\c\\h',
 		'mar' => '3월',
 		'mar' => '3월',
 		'march' => '3월',
 		'march' => '3월',
+		'May' => '\\M\\a\\y',
 		'may' => '5월',
 		'may' => '5월',
 		'may_' => '5월',
 		'may_' => '5월',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
 		'mon' => '월',
 		'mon' => '월',
 		'month' => '개월',
 		'month' => '개월',
 		'nov' => '11월',
 		'nov' => '11월',
 		'november' => '11월',
 		'november' => '11월',
+		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',
 		'oct' => '10월',
 		'oct' => '10월',
 		'october' => '10월',
 		'october' => '10월',
 		'sat' => '토',
 		'sat' => '토',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
 		'sep' => '9월',
 		'sep' => '9월',
 		'september' => '9월',
 		'september' => '9월',
 		'sun' => '일',
 		'sun' => '일',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -160,7 +161,6 @@ return array(
 		'previous' => 'Previous',
 		'previous' => 'Previous',
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => '메일',
 		'email' => '메일',
@@ -168,9 +168,11 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'gnusocial' => 'GNU social',
 		'gnusocial' => 'GNU social',
 		'jdh' => 'Journal du hacker',
 		'jdh' => 'Journal du hacker',
+		'Known' => 'Known based sites',
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => '인쇄',
 		'print' => '인쇄',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',

+ 3 - 3
app/i18n/kr/index.php

@@ -40,7 +40,7 @@ return array(
 		'mark_all_read' => '모두 읽음으로 표시',
 		'mark_all_read' => '모두 읽음으로 표시',
 		'mark_cat_read' => '카테고리를 읽음으로 표시',
 		'mark_cat_read' => '카테고리를 읽음으로 표시',
 		'mark_feed_read' => '피드를 읽음으로 표시',
 		'mark_feed_read' => '피드를 읽음으로 표시',
-		'mark_selection_unread' => 'Mark selection as unread',	//TODO
+		'mark_selection_unread' => 'Mark selection as unread',	//TODO - Translation
 		'newer_first' => '최근 글 먼저',
 		'newer_first' => '최근 글 먼저',
 		'non-starred' => '즐겨찾기를 제외하고 표시',
 		'non-starred' => '즐겨찾기를 제외하고 표시',
 		'normal_view' => '일반 모드',
 		'normal_view' => '일반 모드',
@@ -53,11 +53,11 @@ return array(
 		'starred' => '즐겨찾기만 표시',
 		'starred' => '즐겨찾기만 표시',
 		'stats' => '통계',
 		'stats' => '통계',
 		'subscription' => '구독 관리',
 		'subscription' => '구독 관리',
-		'tags' => 'My labels',	//TODO
+		'tags' => 'My labels',	//TODO - Translation
 		'unread' => '읽지 않은 글만 표시',
 		'unread' => '읽지 않은 글만 표시',
 	),
 	),
 	'share' => '공유',
 	'share' => '공유',
 	'tag' => array(
 	'tag' => array(
-		'related' => '관련 태그',	//TODO
+		'related' => '관련 태그',	//TODO - Translation
 	),
 	),
 );
 );

+ 3 - 3
app/i18n/kr/install.php

@@ -24,8 +24,8 @@ return array(
 			'ok' => '데이터베이스 설정이 저장되었습니다.',
 			'ok' => '데이터베이스 설정이 저장되었습니다.',
 		),
 		),
 		'host' => '데이터베이스 서버',
 		'host' => '데이터베이스 서버',
-		'prefix' => '테이블 접두어',
 		'password' => '데이터베이스 암호',
 		'password' => '데이터베이스 암호',
+		'prefix' => '테이블 접두어',
 		'type' => '데이터베이스 종류',
 		'type' => '데이터베이스 종류',
 		'username' => '데이터베이스 사용자 이름',
 		'username' => '데이터베이스 사용자 이름',
 	),
 	),
@@ -69,8 +69,8 @@ return array(
 			'ok' => 'JSON  확장 기능이 설치되어 있습니다.',
 			'ok' => 'JSON  확장 기능이 설치되어 있습니다.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Minz 프레임워크를 찾을 수 없습니다.',
 			'nok' => 'Minz 프레임워크를 찾을 수 없습니다.',

+ 9 - 2
app/i18n/kr/sub.php

@@ -27,7 +27,7 @@ return array(
 			'password' => 'HTTP 암호',
 			'password' => 'HTTP 암호',
 			'username' => 'HTTP 사용자 이름',
 			'username' => 'HTTP 사용자 이름',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	//TODO
+		'clear_cache' => 'Always clear cache',	//TODO - Translation
 		'css_help' => '글의 일부가 포함된 RSS 피드를 가져옵니다 (주의, 시간이 좀 더 걸립니다!)',
 		'css_help' => '글의 일부가 포함된 RSS 피드를 가져옵니다 (주의, 시간이 좀 더 걸립니다!)',
 		'css_path' => '웹사이트 상의 글 본문에 해당하는 CSS 경로',
 		'css_path' => '웹사이트 상의 글 본문에 해당하는 CSS 경로',
 		'description' => '설명',
 		'description' => '설명',
@@ -45,6 +45,14 @@ return array(
 			'main_stream' => '메인 스트림에 표시하기',
 			'main_stream' => '메인 스트림에 표시하기',
 			'normal' => '피드가 속한 카테고리에만 표시하기',
 			'normal' => '피드가 속한 카테고리에만 표시하기',
 		),
 		),
+		'websub' => 'WebSub을 사용한 즉시 알림',
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
 		'ssl_verify' => 'SSL 유효성 검사',
 		'ssl_verify' => 'SSL 유효성 검사',
 		'stats' => '통계',
 		'stats' => '통계',
 		'think_to_add' => '피드를 추가할 수 있습니다.',
 		'think_to_add' => '피드를 추가할 수 있습니다.',
@@ -55,7 +63,6 @@ return array(
 		'url' => '피드 URL',
 		'url' => '피드 URL',
 		'validator' => '피드 유효성 검사',
 		'validator' => '피드 유효성 검사',
 		'website' => '웹사이트 URL',
 		'website' => '웹사이트 URL',
-		'pubsubhubbub' => 'PubSubHubbub을 사용한 즉시 알림',
 	),
 	),
 	'firefox' => array(
 	'firefox' => array(
 		'documentation' => 'FreshRSS를 Firefox 피드 리더에 추가하기 위해서는 <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">여기</a>의 설명을 따르세요.',
 		'documentation' => 'FreshRSS를 Firefox 피드 리더에 추가하기 위해서는 <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">여기</a>의 설명을 따르세요.',

+ 10 - 11
app/i18n/nl/admin.php

@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Auteur',
+		'community' => 'Gebruikersuitbreidingen beschikbaar',
+		'description' => 'Beschrijving',
 		'disabled' => 'Uitgeschakeld',
 		'disabled' => 'Uitgeschakeld',
 		'empty_list' => 'Er zijn geïnstalleerde uitbreidingen',
 		'empty_list' => 'Er zijn geïnstalleerde uitbreidingen',
 		'enabled' => 'Ingeschakeld',
 		'enabled' => 'Ingeschakeld',
+		'latest' => 'Geïnstalleerd',
+		'name' => 'Naam',
 		'no_configure_view' => 'Deze uitbreiding kan niet worden geconfigureerd.',
 		'no_configure_view' => 'Deze uitbreiding kan niet worden geconfigureerd.',
 		'system' => array(
 		'system' => array(
 			'_' => 'Systeemuitbreidingen',
 			'_' => 'Systeemuitbreidingen',
 			'no_rights' => 'Systeemuitbreidingen (U hebt hier geen rechten op)',
 			'no_rights' => 'Systeemuitbreidingen (U hebt hier geen rechten op)',
 		),
 		),
 		'title' => 'Uitbreidingen',
 		'title' => 'Uitbreidingen',
+		'update' => 'Update beschikbaar',
 		'user' => 'Gebruikersuitbreidingen',
 		'user' => 'Gebruikersuitbreidingen',
-		'community' => 'Gebruikersuitbreidingen beschikbaar',
-		'name' => 'Naam',
 		'version' => 'Versie',
 		'version' => 'Versie',
-		'description' => 'Beschrijving',
-		'author' => 'Auteur',
-		'latest' => 'Geïnstalleerd',
-		'update' => 'Update beschikbaar',
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistieken',
 		'_' => 'Statistieken',
@@ -162,6 +162,10 @@ return array(
 		'instance-name' => 'Voorbeeld naam',
 		'instance-name' => 'Voorbeeld naam',
 		'max-categories' => 'Categoriën limiet per gebruiker',
 		'max-categories' => 'Categoriën limiet per gebruiker',
 		'max-feeds' => 'Feed limiet per gebruiker',
 		'max-feeds' => 'Feed limiet per gebruiker',
+		'cookie-duration' => array(
+			'help' => 'in seconds', // @todo translate
+			'number' => 'Duration to keep logged in', // @todo translate
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 betekent geen account limiet',
 			'help' => '0 betekent geen account limiet',
 			'number' => 'Maximum aantal accounts',
 			'number' => 'Maximum aantal accounts',
@@ -185,11 +189,6 @@ return array(
 		'numbers' => 'Er zijn %d accounts gemaakt',
 		'numbers' => 'Er zijn %d accounts gemaakt',
 		'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier loginmethode)</small>',
 		'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier loginmethode)</small>',
 		'password_format' => 'Ten minste 7 tekens',
 		'password_format' => 'Ten minste 7 tekens',
-		'registration' => array(
-			'allow' => 'Sta het maken van nieuwe accounts toe',
-			'help' => '0 betekent dat er geen accountlimiet is',
-			'number' => 'Max aantal accounts',
-		),
 		'selected' => 'Geselecteerde gebruiker',
 		'selected' => 'Geselecteerde gebruiker',
 		'title' => 'Beheer gebruikers',
 		'title' => 'Beheer gebruikers',
 		'update_users' => 'Gebruiker bijwerken',
 		'update_users' => 'Gebruiker bijwerken',

+ 18 - 15
app/i18n/nl/conf.php

@@ -19,7 +19,7 @@ return array(
 			'bottom_line' => 'Onderaan',
 			'bottom_line' => 'Onderaan',
 			'entry' => 'Artikel pictogrammen',
 			'entry' => 'Artikel pictogrammen',
 			'publication_date' => 'Publicatie datum',
 			'publication_date' => 'Publicatie datum',
-			'related_tags' => 'Gerelateerde labels',	//TODO
+			'related_tags' => 'Gerelateerde labels',
 			'sharing' => 'Delen',
 			'sharing' => 'Delen',
 			'top_line' => 'Bovenaan',
 			'top_line' => 'Bovenaan',
 		),
 		),
@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'seconden (0 betekent geen stop)',
 			'seconds' => 'seconden (0 betekent geen stop)',
 			'timeout' => 'HTML5 notificatie stop',
 			'timeout' => 'HTML5 notificatie stop',
 		),
 		),
+		'show_nav_buttons' => 'Toon navigatieknoppen',
 		'theme' => 'Thema',
 		'theme' => 'Thema',
 		'title' => 'Opmaak',
 		'title' => 'Opmaak',
 		'width' => array(
 		'width' => array(
@@ -37,7 +38,17 @@ return array(
 			'no_limit' => 'Geen limiet',
 			'no_limit' => 'Geen limiet',
 			'thin' => 'Smal',
 			'thin' => 'Smal',
 		),
 		),
-		'show_nav_buttons' => 'Toon navigatieknoppen',
+	),
+	'profile' => array(
+		'_' => 'Profiel beheer',
+		'delete' => array(
+			'_' => 'Account verwijderen',
+			'warn' => 'Uw account en alle gerelateerde gegvens worden verwijderd.',
+		),
+		'password_api' => 'Wachtwoord API<br /><small>(e.g., voor mobiele apps)</small>',
+		'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier log in methode)</small>',
+		'password_format' => 'Ten minste 7 tekens',
+		'title' => 'Profiel',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'Gebruikersquery\'s (informatie aanvragen)',
 		'_' => 'Gebruikersquery\'s (informatie aanvragen)',
@@ -73,17 +84,6 @@ return array(
 		'state_15' => 'Toon alle artikelen',
 		'state_15' => 'Toon alle artikelen',
 		'title' => 'Gebruikersquery\'s',
 		'title' => 'Gebruikersquery\'s',
 	),
 	),
-	'profile' => array(
-		'_' => 'Profiel beheer',
-		'delete' => array(
-			'_' => 'Account verwijderen',
-			'warn' => 'Uw account en alle gerelateerde gegvens worden verwijderd.',
-		),
-		'password_api' => 'Wachtwoord API<br /><small>(e.g., voor mobiele apps)</small>',
-		'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier log in methode)</small>',
-		'password_format' => 'Ten minste 7 tekens',
-		'title' => 'Profiel',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Lezen',
 		'_' => 'Lezen',
 		'after_onread' => 'Na “markeer alles als gelezen”,',
 		'after_onread' => 'Na “markeer alles als gelezen”,',
@@ -95,7 +95,6 @@ return array(
 		'display_categories_unfolded' => 'Toon categoriën ingeklapt als standaard',
 		'display_categories_unfolded' => 'Toon categoriën ingeklapt als standaard',
 		'hide_read_feeds' => 'Verberg categoriën en feeds zonder ongelezen artikelen (werkt niet met “Toon alle artikelen” configuratie)',
 		'hide_read_feeds' => 'Verberg categoriën en feeds zonder ongelezen artikelen (werkt niet met “Toon alle artikelen” configuratie)',
 		'img_with_lazyload' => 'Gebruik "lazy load" methode om afbeeldingen te laden',
 		'img_with_lazyload' => 'Gebruik "lazy load" methode om afbeeldingen te laden',
-		'sides_close_article' => 'Sluit het artikel door buiten de artikeltekst te klikken',
 		'jump_next' => 'Ga naar volgende ongelezen (feed of categorie)',
 		'jump_next' => 'Ga naar volgende ongelezen (feed of categorie)',
 		'mark_updated_article_unread' => 'Markeer vernieuwd artikel als ongelezen',
 		'mark_updated_article_unread' => 'Markeer vernieuwd artikel als ongelezen',
 		'number_divided_when_reader' => 'Gedeeld door 2 in de lees modus.',
 		'number_divided_when_reader' => 'Gedeeld door 2 in de lees modus.',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => 'Bekijk alle artikelen',
 			'all_articles' => 'Bekijk alle artikelen',
 			'unread' => 'Bekijk alleen ongelezen',
 			'unread' => 'Bekijk alleen ongelezen',
 		),
 		),
+		'sides_close_article' => 'Sluit het artikel door buiten de artikeltekst te klikken',
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Sorteer volgorde',
 			'_' => 'Sorteer volgorde',
 			'newer_first' => 'Nieuwste eerst',
 			'newer_first' => 'Nieuwste eerst',
@@ -158,10 +158,11 @@ return array(
 		'javascript' => 'JavaScript moet geactiveerd zijn om verwijzingen te gebruiken',
 		'javascript' => 'JavaScript moet geactiveerd zijn om verwijzingen te gebruiken',
 		'last_article' => 'Spring naar laatste artikel',
 		'last_article' => 'Spring naar laatste artikel',
 		'load_more' => 'Laad meer artikelen',
 		'load_more' => 'Laad meer artikelen',
-		'mark_read' => 'Markeer als gelezen',
 		'mark_favorite' => 'Markeer als favoriet',
 		'mark_favorite' => 'Markeer als favoriet',
+		'mark_read' => 'Markeer als gelezen',
 		'navigation' => 'Navigatie',
 		'navigation' => 'Navigatie',
 		'navigation_help' => 'Met de "Shift" toets, kunt u navigatie verwijzingen voor feeds gebruiken.<br/>Met de "Alt" toets, kunt u navigatie verwijzingen voor categoriën gebruiken.',
 		'navigation_help' => 'Met de "Shift" toets, kunt u navigatie verwijzingen voor feeds gebruiken.<br/>Met de "Alt" toets, kunt u navigatie verwijzingen voor categoriën gebruiken.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => 'Spring naar volgende artikel',
 		'next_article' => 'Spring naar volgende artikel',
 		'normal_view' => 'Schakel naar gewoon aanzicht',
 		'normal_view' => 'Schakel naar gewoon aanzicht',
 		'other_action' => 'Andere acties',
 		'other_action' => 'Andere acties',
@@ -170,6 +171,8 @@ return array(
 		'rss_view' => 'Open RSS-aanzicht in een nieuwe tab',
 		'rss_view' => 'Open RSS-aanzicht in een nieuwe tab',
 		'see_on_website' => 'Bekijk op originale website',
 		'see_on_website' => 'Bekijk op originale website',
 		'shift_for_all_read' => '+ <code>shift</code> om alle artikelen als gelezen te markeren',
 		'shift_for_all_read' => '+ <code>shift</code> om alle artikelen als gelezen te markeren',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => 'Verwijzingen',
 		'title' => 'Verwijzingen',
 		'user_filter' => 'Toegang gebruikers filters',
 		'user_filter' => 'Toegang gebruikers filters',
 		'user_filter_help' => 'Als er slechts één gebruikersfilter is, dan wordt die gebruikt. Anders zijn ze toegankelijk met hun nummer.',
 		'user_filter_help' => 'Als er slechts één gebruikersfilter is, dan wordt die gebruikt. Anders zijn ze toegankelijk met hun nummer.',

+ 4 - 5
app/i18n/nl/feedback.php

@@ -50,6 +50,10 @@ return array(
 		'no_zip_extension' => 'ZIP uitbreiding is niet aanwezig op uw server.',
 		'no_zip_extension' => 'ZIP uitbreiding is niet aanwezig op uw server.',
 		'zip_error' => 'Er is een fout opgetreden tijdens het imporeren van het ZIP bestand.',
 		'zip_error' => 'Er is een fout opgetreden tijdens het imporeren van het ZIP bestand.',
 	),
 	),
+	'profile' => array(
+		'error' => 'Uw profiel kan niet worden aangepast',
+		'updated' => 'Uw profiel is aangepast',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Actualiseren',
 		'actualize' => 'Actualiseren',
 		'articles' => array(
 		'articles' => array(
@@ -108,10 +112,5 @@ return array(
 			'_' => 'Gebruiker %s is bijgewerkt',
 			'_' => 'Gebruiker %s is bijgewerkt',
 			'error' => 'Gebruiker %s kan niet worden bijgewerkt',
 			'error' => 'Gebruiker %s kan niet worden bijgewerkt',
 		),
 		),
-		'set_registration' => 'Het maximale aantal accounts is vernieuwd.',
-	),
-	'profile' => array(
-		'error' => 'Uw profiel kan niet worden aangepast',
-		'updated' => 'Uw profiel is aangepast',
 	),
 	),
 );
 );

+ 14 - 12
app/i18n/nl/gen.php

@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\A\\p\\r\\i\\l',
 		'Apr' => '\\A\\p\\r\\i\\l',
-		'Aug' => '\\A\\u\\g\\u\\s\\t\\u\\s',
-		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
-		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\i',
-		'Jan' => '\\J\\a\\n\\u\\a\\r\\i',
-		'Jul' => '\\J\\u\\l\\i',
-		'Jun' => '\\J\\u\\n\\i',
-		'Mar' => '\\M\\a\\a\\r\\t',
-		'May' => '\\M\\e\\i',
-		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
-		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
-		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
 		'apr' => 'apr',
 		'apr' => 'apr',
 		'april' => 'Apr',
 		'april' => 'Apr',
+		'Aug' => '\\A\\u\\g\\u\\s\\t\\u\\s',
 		'aug' => 'aug',
 		'aug' => 'aug',
 		'august' => 'Aug',
 		'august' => 'Aug',
 		'before_yesterday' => 'Ouder',
 		'before_yesterday' => 'Ouder',
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
 		'dec' => 'dec',
 		'dec' => 'dec',
 		'december' => 'Dec',
 		'december' => 'Dec',
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\i',
 		'feb' => 'feb',
 		'feb' => 'feb',
 		'february' => 'Feb',
 		'february' => 'Feb',
 		'format_date' => 'j %s Y',
 		'format_date' => 'j %s Y',
 		'format_date_hour' => 'j %s Y \\o\\m H\\:i',
 		'format_date_hour' => 'j %s Y \\o\\m H\\:i',
 		'fri' => 'Vr',
 		'fri' => 'Vr',
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\i',
 		'jan' => 'jan',
 		'jan' => 'jan',
 		'january' => 'Jan',
 		'january' => 'Jan',
+		'Jul' => '\\J\\u\\l\\i',
 		'jul' => 'jul',
 		'jul' => 'jul',
 		'july' => 'Jul',
 		'july' => 'Jul',
+		'Jun' => '\\J\\u\\n\\i',
 		'jun' => 'jun',
 		'jun' => 'jun',
 		'june' => 'Jun',
 		'june' => 'Jun',
 		'last_3_month' => 'Laatste drie maanden',
 		'last_3_month' => 'Laatste drie maanden',
@@ -78,17 +73,22 @@ return array(
 		'last_month' => 'Vorige maand',
 		'last_month' => 'Vorige maand',
 		'last_week' => 'Vorige week',
 		'last_week' => 'Vorige week',
 		'last_year' => 'Vorig jaar',
 		'last_year' => 'Vorig jaar',
+		'Mar' => '\\M\\a\\a\\r\\t',
 		'mar' => 'mrt',
 		'mar' => 'mrt',
 		'march' => 'Mrt',
 		'march' => 'Mrt',
+		'May' => '\\M\\e\\i',
 		'may' => 'Mei',
 		'may' => 'Mei',
 		'may_' => 'Mei',
 		'may_' => 'Mei',
 		'mon' => 'Ma',
 		'mon' => 'Ma',
 		'month' => 'maanden',
 		'month' => 'maanden',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
 		'nov' => 'nov',
 		'nov' => 'nov',
 		'november' => 'Nov',
 		'november' => 'Nov',
+		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
 		'oct' => 'okt',
 		'oct' => 'okt',
 		'october' => 'Okt',
 		'october' => 'Okt',
 		'sat' => 'Za',
 		'sat' => 'Za',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
 		'sep' => 'sep',
 		'sep' => 'sep',
 		'september' => 'Sep',
 		'september' => 'Sep',
 		'sun' => 'Zo',
 		'sun' => 'Zo',
@@ -124,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -160,7 +161,6 @@ return array(
 		'previous' => 'Vorige',
 		'previous' => 'Vorige',
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -168,9 +168,11 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'gnusocial' => 'GNU social',
 		'gnusocial' => 'GNU social',
 		'jdh' => 'Journal du hacker',
 		'jdh' => 'Journal du hacker',
+		'Known' => 'Known based sites',
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Print',
 		'print' => 'Print',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',

+ 2 - 1
app/i18n/nl/index.php

@@ -53,10 +53,11 @@ return array(
 		'starred' => 'Laat alleen favorieten zien',
 		'starred' => 'Laat alleen favorieten zien',
 		'stats' => 'Statistieken',
 		'stats' => 'Statistieken',
 		'subscription' => 'Abonnementen beheer',
 		'subscription' => 'Abonnementen beheer',
+		'tags' => 'My labels',	//TODO - Translation
 		'unread' => 'Laat alleen ongelezen zien',
 		'unread' => 'Laat alleen ongelezen zien',
 	),
 	),
 	'share' => 'Delen',
 	'share' => 'Delen',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Verwante labels',	//TODO
+		'related' => 'Verwante labels',	//TODO - Translation
 	),
 	),
 );
 );

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

@@ -24,8 +24,8 @@ return array(
 			'ok' => 'Database configuratie is opgeslagen.',
 			'ok' => 'Database configuratie is opgeslagen.',
 		),
 		),
 		'host' => 'Host',
 		'host' => 'Host',
-		'prefix' => 'Tabel voorvoegsel',
 		'password' => 'Database wachtwoord',
 		'password' => 'Database wachtwoord',
+		'prefix' => 'Tabel voorvoegsel',
 		'type' => 'Type database',
 		'type' => 'Type database',
 		'username' => 'Database gebruikersnaam',
 		'username' => 'Database gebruikersnaam',
 	),
 	),

+ 9 - 2
app/i18n/nl/sub.php

@@ -27,7 +27,7 @@ return array(
 			'password' => 'HTTP wachtwoord',
 			'password' => 'HTTP wachtwoord',
 			'username' => 'HTTP gebruikers naam',
 			'username' => 'HTTP gebruikers naam',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	//TODO
+		'clear_cache' => 'Always clear cache',	//TODO - Translation
 		'css_help' => 'Haalt verstoorde RSS feeds op (attentie, heeft meer tijd nodig!)',
 		'css_help' => 'Haalt verstoorde RSS feeds op (attentie, heeft meer tijd nodig!)',
 		'css_path' => 'Artikelen CSS pad op originele website',
 		'css_path' => 'Artikelen CSS pad op originele website',
 		'description' => 'Omschrijving',
 		'description' => 'Omschrijving',
@@ -45,7 +45,14 @@ return array(
 			'main_stream' => 'Zichtbaar in het overzicht',
 			'main_stream' => 'Zichtbaar in het overzicht',
 			'normal' => 'Toon in categorie',
 			'normal' => 'Toon in categorie',
 		),
 		),
-		'pubsubhubbub' => 'Directe notificaties met PubSubHubbub',
+		'websub' => 'Directe notificaties met WebSub',
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
 		'ssl_verify' => 'SSL-veiligheid controleren',
 		'ssl_verify' => 'SSL-veiligheid controleren',
 		'stats' => 'Statistieken',
 		'stats' => 'Statistieken',
 		'think_to_add' => 'Voeg wat feeds toe.',
 		'think_to_add' => 'Voeg wat feeds toe.',

+ 199 - 0
app/i18n/oc/admin.php

@@ -0,0 +1,199 @@
+<?php
+
+return array(
+	'auth' => array(
+		'allow_anonymous' => 'Autorizar la lectura anonima dels articles de l’utilizaire per defaut (%s)',
+		'allow_anonymous_refresh' => 'Autorizar l’actualizacion anonime dels fluxes',
+		'api_enabled' => 'Autorizar l’accès per <abbr>API</abbr><small>(necessari per las aplicacions mobil)</small>',
+		'form' => 'Formulari (tradicional, demanda JavaScript)',
+		'http' => 'HTTP (per utilizaires avançats amb HTTPS)',
+		'none' => 'Cap (perilhós)',
+		'title' => 'Autentificacion',
+		'title_reset' => 'Reïnicializacion de l’autentificacion',
+		'token' => 'Geton d’autentificacion',
+		'token_help' => 'Permetre l’accès a la sortida RSS de l’utilizaire per defaut sens cap d’autentificacion :',
+		'type' => 'Mòde d’autentification',
+		'unsafe_autologin' => 'Autorizar las connexions automaticas pas seguras al format : ',
+	),
+	'check_install' => array(
+		'cache' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data/cache</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul cache son bons.',
+		),
+		'categories' => array(
+			'nok' => 'La tabla “category” es mala configurada.',
+			'ok' => 'La tabla category es corrèctament configurada.',
+		),
+		'connection' => array(
+			'nok' => 'Connexion impossibla a la basa de donadas.',
+			'ok' => 'La connexion a la basa de donadas es bona.',
+		),
+		'ctype' => array(
+			'nok' => 'Impossible de trobar una bibliotèca per la verificacion del tipe de caractèrs (php-ctype).',
+			'ok' => 'Avètz la bibliotèca per la verificacion del tipe de caractèrs (ctype).',
+		),
+		'curl' => array(
+			'nok' => 'Impossible de trobar la bibliotèca cURL( paquet php-curl).',
+			'ok' => 'Avètz la bibliotèca cURL.',
+		),
+		'data' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul repertòri data son bons.',
+		),
+		'database' => 'Installacion de la basa de donadas',
+		'dom' => array(
+			'nok' => 'Impossible de trobar una bibliotèca per percórrer lo DOM (paquet php-xml).',
+			'ok' => 'Avètz la bibliotèca per percórrer lo DOM.',
+		),
+		'entries' => array(
+			'nok' => 'La tabla entry es pas configurada coma cal.',
+			'ok' => 'La tabla entry es corrèctament configurada.',
+		),
+		'favicons' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data/favicons</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul repertòri dels favicons son bons.',
+		),
+		'feeds' => array(
+			'nok' => 'La tabla feed es pas configurada coma cal.',
+			'ok' => 'La tabla feed es corrèctament configurada.',
+		),
+		'fileinfo' => array(
+			'nok' => 'Avètz pas PHP fileinfo (paquet fileinfo).',
+			'ok' => 'Avètz la bibliotèca fileinfo.',
+		),
+		'files' => 'Installacion dels fichièrs',
+		'json' => array(
+			'nok' => 'Avètz pas l’extension recomandada JSON (paquet php-json).',
+			'ok' => 'Avètz l’exension recomandada JSON.',
+		),
+		'mbstring' => array(
+			'nok' => 'Impossible de trobar la bibliotèca recomandada mbstring per Unicode.',
+			'ok' => 'Avètz la bibliotèca recomandada mbstring per Unicode.',
+		),
+		'minz' => array(
+			'nok' => 'Avètz pas la bibliotèca Minz.',
+			'ok' => 'Avètz la bibliotèca Minz.',
+		),
+		'pcre' => array(
+			'nok' => 'Impossible de trobar una bibliotèca per las expressions regulara (php-pcre).',
+			'ok' => 'Avètz la bibliotèca per las expressions regularas (PCRE).',
+		),
+		'pdo' => array(
+			'nok' => 'Impossible de trobar PDO o un dels drivers compatibles (pdo_mysql, pdo_sqlite, pdo_pgsql).',
+			'ok' => 'Avètz PDO e almens un des drivers compatibles (pdo_mysql, pdo_sqlite, pdo_pgsql).',
+		),
+		'php' => array(
+			'_' => 'Installacion PHP',
+			'nok' => 'Vòstra version PHP es la %s más FreshRSS demanda almens la versión %s.',
+			'ok' => 'Vòstra version PHP es %s, qu’es compatibla amb FreshRSS.',
+		),
+		'tables' => array(
+			'nok' => 'Manca una o mai tabla dins la basa de donadas.',
+			'ok' => 'Las tablas que cal existisson ben dins la basa de donadas.',
+		),
+		'title' => 'Verificacion de l’installacion',
+		'tokens' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data/tokens</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul repertòri dels getons son bons.',
+		),
+		'users' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data/users</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul repertòri dels utilizaires son bons.',
+		),
+		'zip' => array(
+			'nok' => 'Avètz pas l’extension ZIP (paquet php-zip).',
+			'ok' => 'Avètz l’exension ZIP.',
+		),
+	),
+	'extensions' => array(
+		'author' => 'Autor',
+		'community' => 'Extensions utilizaires disponiblas',
+		'description' => 'Descripcion',
+		'disabled' => 'Desactivada',
+		'empty_list' => 'Cap d’extensions pas installadas',
+		'enabled' => 'Activada',
+		'latest' => 'Installada',
+		'name' => 'Nom',
+		'no_configure_view' => 'Aquesta extension se pòt pas configurar.',
+		'system' => array(
+			'_' => 'Extensions sistèma',
+			'no_rights' => 'Extensions sistèma (contrarotlat per l’administrator)',
+		),
+		'title' => 'Extensions',
+		'update' => 'Mesa a jorn disponibla',
+		'user' => 'Extensions utilizaire',
+		'version' => 'Version',
+	),
+	'stats' => array(
+		'_' => 'Estatisticas',
+		'all_feeds' => 'Totes los fluxes',
+		'category' => 'Categoria',
+		'entry_count' => 'Nombre d’articles',
+		'entry_per_category' => 'Articles per categoria',
+		'entry_per_day' => 'Nombre d’articles per jorn (30 darrièrs jorns)',
+		'entry_per_day_of_week' => 'Per jorn de la setmana (mejana : %.2f messatges)',
+		'entry_per_hour' => 'Per ora (mejana : %.2f messatges)',
+		'entry_per_month' => 'Per mes (mejana : %.2f messatges)',
+		'entry_repartition' => 'Reparticion dels articles',
+		'feed' => 'Flux',
+		'feed_per_category' => 'Fluxes per categoria',
+		'idle' => 'Fluxes inactius',
+		'main' => 'Estatisticas principalas',
+		'main_stream' => 'Flux màger',
+		'menu' => array(
+			'idle' => 'Fluxes inactius',
+			'main' => 'Estatisticas principalas',
+			'repartition' => 'Reparticion dels articles',
+		),
+		'no_idle' => 'I a pas cap d’article inactiu !',
+		'number_entries' => '%d articles',
+		'percent_of_total' => '%% del total',
+		'repartition' => 'Reparticion dels articles',
+		'status_favorites' => 'Favorits',
+		'status_read' => 'Legit',
+		'status_total' => 'Total',
+		'status_unread' => 'Pas legits',
+		'title' => 'Estatisticas',
+		'top_feed' => 'Los dètz fluxes mai gròsses',
+	),
+	'system' => array(
+		'_' => 'Configuracion sistèma',
+		'auto-update-url' => 'URL del servici de mesa a jorn',
+		'cookie-duration' => array(
+			'help' => 'en segondas',
+			'number' => 'Durada de téner d’ésser connectat',
+		),
+		'instance-name' => 'Nom de l’instància',
+		'max-categories' => 'Limita de categoria per utilizaire',
+		'max-feeds' => 'Limita de fluxes per utilizaire',
+		'registration' => array(
+			'number' => 'Nombre max de comptes',
+			'help' => '0 vòl dire qu’i a pas cap de limita de compte',
+		),
+	),
+	'update' => array(
+		'_' => 'Sistèma de mesa a jorn',
+		'apply' => 'Aplicar',
+		'check' => 'Verificar las mesas a jorn',
+		'current_version' => 'Vòstra version actuala de FreshRSS es %s.',
+		'last' => 'Darrièra verificacion : %s',
+		'none' => 'Cap d’actualizacion d’aplicar',
+		'title' => 'Sistèma de mesa a jorn',
+	),
+	'user' => array(
+		'articles_and_size' => '%s articles (%s)',
+		'create' => 'Crear un nòu utilizaire',
+		'delete_users' => 'Suprimir un utilizaire',
+		'language' => 'Lenga',
+		'number' => '%d compte ja creat',
+		'numbers' => '%d comptes ja creats',
+		'password_form' => 'Senhal <br /><small>(ex. : per la connexion via formulari)</small>',
+		'password_format' => 'Almens 7 caractèrs',
+		'selected' => 'Utilizaire seleccionat',
+		'title' => 'Gestion dels utilizaires',
+		'update_users' => 'Actualizar un utilizaire',
+		'user_list' => 'Lista dels utilizaires',
+		'username' => 'Nom d’utilizaire',
+		'users' => 'Utilizaires',
+	),
+);

+ 187 - 0
app/i18n/oc/conf.php

@@ -0,0 +1,187 @@
+<?php
+
+return array(
+	'archiving' => array(
+		'_' => 'Archivar',
+		'advanced' => 'Avançat',
+		'delete_after' => 'Levar los articles aprèp',
+		'help' => 'Mai d’opcions son disponiblas dins la configuracion individuala dels fluxes',
+		'keep_history_by_feed' => 'Nombre minimum d’articles de servar per flux',
+		'optimize' => 'Optimizar la basa de donada',
+		'optimize_help' => 'De far de temps en temps per redusir la talha de la basa de donadas',
+		'purge_now' => 'Purgar ara',
+		'title' => 'Archivar',
+		'ttl' => 'Actualizar pas automaticament mai sovent que',
+	),
+	'display' => array(
+		'_' => 'Afichatge',
+		'icon' => array(
+			'bottom_line' => 'Linha enbàs',
+			'entry' => 'Icònas d’article',
+			'publication_date' => 'Data de publicacion',
+			'related_tags' => 'Etiquetas ligadas',
+			'sharing' => 'Partatge',
+			'top_line' => 'Linha amont',
+		),
+		'language' => 'Lenga',
+		'notif_html5' => array(
+			'seconds' => 'segondas (0 significa cap de timeout)',
+			'timeout' => 'Temps d’afichatge de las notificacions HTML5',
+		),
+		'show_nav_buttons' => 'Mostrar los botons de navigacion',
+		'theme' => 'Tèma',
+		'title' => 'Afichatge',
+		'width' => array(
+			'content' => 'Largor del contengut',
+			'large' => 'Larga',
+			'medium' => 'Mejana',
+			'no_limit' => 'Cap de limit',
+			'thin' => 'Fina',
+		),
+	),
+	'profile' => array(
+		'_' => 'Gestion del perfil',
+		'delete' => array(
+			'_' => 'Supression del compte',
+			'warn' => 'Lo compte e totas las donadas ligadas seràn suprimits.',
+		),
+		'password_api' => 'Senhal API<br /><small>(ex. : per las aplicacions mobil)</small>',
+		'password_form' => 'Senhal API<br /><small>(ex. : per la connexion via formulari)</small>',
+		'password_format' => 'Almens 7 caractèrs',
+		'title' => 'Pefil',
+	),
+	'query' => array(
+		'_' => 'Filtres utilizaires',
+		'deprecated' => 'Aqueste filtre es pas valid. La categoria o lo flux concernit es estat suprimit.',
+		'display' => 'Mostrar los resultats del filtre',
+		'filter' => 'Filtres aplicats :',
+		'get_all' => 'Mostrar totes los articles',
+		'get_category' => 'Mostrar la categoria « %s »',
+		'get_favorite' => 'Mostrar los articles favorits',
+		'get_feed' => 'Mostrar lo flux « %s »',
+		'no_filter' => 'Cap de filtre aplicat',
+		'none' => 'Avètz pas encara creat cap de filtre.',
+		'number' => 'Filtre n°%d',
+		'order_asc' => 'Mostrar los articles mai ancians en primièr',
+		'order_desc' => 'Mostrar los articles mai recents en primièr',
+		'remove' => 'Levar lo filtre utilizaire',
+		'search' => 'Recèrca de « %s »',
+		'state_0' => 'Mostrar totes los articles',
+		'state_1' => 'Mostrar los articles pas legits',
+		'state_2' => 'Mostrar los articles pas legits',
+		'state_3' => 'Mostrar totes los articles',
+		'state_4' => 'Mostrar los articles favorits',
+		'state_5' => 'Mostrar los articles legits e en favorits',
+		'state_6' => 'Mostrar los articles pas legits e en favorit',
+		'state_7' => 'Mostrar los articles favorits',
+		'state_8' => 'Mostrar los articles pas en favorit',
+		'state_9' => 'Mostrar los articles legits e pas en favorit',
+		'state_10' => 'Mostrar los articles pas legits e pas en favorit',
+		'state_11' => 'Mostrar los articles pas en favorit',
+		'state_12' => 'Mostrar totes los articles',
+		'state_13' => 'Mostrar los articles legits',
+		'state_14' => 'Mostrar los articles pas legits',
+		'state_15' => 'Mostrar totes los articles',
+		'title' => 'Filtres utilizaire',
+	),
+	'reading' => array(
+		'_' => 'Lectura',
+		'after_onread' => 'Aprèp « marcar coma legit »,',
+		'articles_per_page' => 'Nombre d’articles per pagina',
+		'auto_load_more' => 'Cargar los articles seguents enbàs de la pagina',
+		'auto_remove_article' => 'Rescondre los articles aprèp lectura',
+		'confirm_enabled' => 'Mostrar una confirmacion per las accions del tipe « o marcar tot coma legit »',
+		'display_articles_unfolded' => 'Mostrar los articles desplegats per defaut',
+		'display_categories_unfolded' => 'Mostrar las categorias plegadas per defaut',
+		'hide_read_feeds' => 'Rescondre las categorias & fluxes sens articles pas legits (fonciona pas amb la configuracion « Mostrar totes los articles »)',
+		'img_with_lazyload' => 'Utilizar lo mòde “cargament tardiu” per las imatges',
+		'jump_next' => 'sautar al vesin venent pas legit (flux o categoria)',
+		'mark_updated_article_unread' => 'Marcar los articles actualizats coma pas legits',
+		'number_divided_when_reader' => 'Devisat per 2 dins la vista de lectura.',
+		'read' => array(
+			'article_open_on_website' => 'quand l’article es dobèrt sul site d’origina',
+			'article_viewed' => 'quand l’article es mostrat',
+			'scroll' => 'en davalant la pagina',
+			'upon_reception' => 'en recebre un article novèl',
+			'when' => 'Marcar un article coma legit…',
+		),
+		'show' => array(
+			'_' => 'Articles de mostrar',
+			'adaptive' => 'Adaptar l’afichatge',
+			'all_articles' => 'Mostrar totes los articles',
+			'unread' => 'Mostrar pas que los pas legits',
+		),
+		'sides_close_article' => 'Clicar fòra de la zòna de tèxte tampa l’article',
+		'sort' => array(
+			'_' => 'Òrdre de tria',
+			'newer_first' => 'Mai recents en primièr',
+			'older_first' => 'Mai ancians en primièr',
+		),
+		'sticky_post' => 'Gardar l’article amont quand es dobèrt',
+		'title' => 'Lectura',
+		'view' => array(
+			'default' => 'Vista per defaut',
+			'global' => 'Vista generala',
+			'normal' => 'Vista normala',
+			'reader' => 'Vista lectura',
+		),
+	),
+	'sharing' => array(
+		'_' => 'Partatge',
+		'add' => 'Ajustar un metòde de partatge',
+		'blogotext' => 'Blogotext',
+		'diaspora' => 'Diaspora*',
+		'email' => 'Corrièl',
+		'facebook' => 'Facebook',
+		'g+' => 'Google+',
+		'more_information' => 'Mai d’informacions',
+		'print' => 'Imprimir',
+		'remove' => 'Suprimir lo metòde de partatge',
+		'shaarli' => 'Shaarli',
+		'share_name' => 'Nom del partatge de mostrar',
+		'share_url' => 'URL del partatge d’utilizar',
+		'title' => 'Partatge',
+		'twitter' => 'Twitter',
+		'wallabag' => 'wallabag',
+	),
+	'shortcut' => array(
+		'_' => 'Acorchis',
+		'article_action' => 'Accions ligadas a l’article',
+		'auto_share' => 'Partejar',
+		'auto_share_help' => 'S’i a pas qu’un mòde de partatge, aquel serà utilizat. Autrament los mòdes son accessibles per lor numèro.',
+		'close_dropdown' => 'Tampar los menús',
+		'collapse_article' => 'Replegar',
+		'first_article' => 'Passar al primièr article',
+		'focus_search' => 'Accedir a la recèrca',
+		'global_view' => 'Passar a la vista generala',
+		'help' => 'Mostrar la documentacion',
+		'javascript' => 'Devètz activar lo Javascript per utilizar los acorchis',
+		'last_article' => 'Passar al darrièr article',
+		'load_more' => 'Cargar mai d’articles',
+		'mark_favorite' => 'Ajustar als favorits',
+		'mark_read' => 'Marcar coma legit',
+		'navigation' => 'Navigacion',
+		'navigation_help' => 'Amb lo modificador «Shift», los acorchis de navigacion s’aplican als fluxes.<br/>Amb lo modificador «Alt», los acorchis de navigacion s’aplican a las categorias.',
+		'navigation_no_mod_help' => 'Los acorchis clavièrs de navigacion son pas compatibles amb los modificadors.',
+		'next_article' => 'Passar a l’article seguent',
+		'normal_view' => 'Passar a la vista normala',
+		'other_action' => 'Autras accions',
+		'previous_article' => 'Passar a l’article precedent',
+		'reading_view' => 'Passar a la vista lectura',
+		'rss_view' => 'Dobrir la vista RSS dins un onglet novèl',
+		'see_on_website' => 'Veire al site d’origina',
+		'shift_for_all_read' => '+ <code>shift</code> per marcar los articles coma legits',
+		'skip_next_article' => 'Centrar sul seguent sens lo dobrir',
+		'skip_previous_article' => 'Centrar sul precedent sens lo dobrir',
+		'title' => 'Acorchis',
+		'user_filter' => 'Accedir als filtres utilizaire',
+		'user_filter_help' => 'S’i a pas qu’un filtre utilizaire, aquel serà utilizat. Autrament los filtres son accessibles per lor numèro.',
+		'views' => 'Vistas',
+	),
+	'user' => array(
+		'articles_and_size' => '%s articles (%s)',
+		'current' => 'Utilizaire actual',
+		'is_admin' => 'es administrator',
+		'users' => 'Utilizaires',
+	),
+);

+ 116 - 0
app/i18n/oc/feedback.php

@@ -0,0 +1,116 @@
+<?php
+
+return array(
+	'admin' => array(
+		'optimization_complete' => 'Optimizacion acabada',
+	),
+	'access' => array(
+		'denied' => 'Avètz pas l’autorizacion d’accedir a aquesta pagina',
+		'not_found' => 'La pagina que cercatz existís pas',
+	),
+	'auth' => array(
+		'form' => array(
+			'not_set' => 'Un problèma es aparegut pendent la configuracion del sistèma d’autentificacion. Tonatz ensajar ai tard.',
+			'set' => 'Lo sistèma d’autentificacion per defaut es ara lo formulari.',
+		),
+		'login' => array(
+			'invalid' => 'L’identificant es invalid',
+			'success' => 'Sètz connectat',
+		),
+		'logout' => array(
+			'success' => 'Sètz desconnectat',
+		),
+		'no_password_set' => 'Pas de senhal es pas configurat. Aquesta foncionalitat es pas disponibla.',
+	),
+	'conf' => array(
+		'error' => 'Una error es apareguda pendent la salvagarda de la configuracion',
+		'query_created' => 'Lo filtre « %s » es estat creat.',
+		'shortcuts_updated' => 'Los acorchis son actualizats',
+		'updated' => 'La configuracion es estada actualizada',
+	),
+	'extensions' => array(
+		'already_enabled' => '%s es ja activada',
+		'disable' => array(
+			'ko' => '%s pòt pas èsser desactivada. <a href="%s">Consultatz los jornals d’audit de FreshRSS logs</a> per mai de detalhs.',
+			'ok' => '%s es ara desactivada',
+		),
+		'enable' => array(
+			'ko' => '%s pòt pas èsser activada. <a href="%s">Consultatz los jornals d’audit de FreshRSS logs</a> per mai de detalhs.',
+			'ok' => '%s es ara activada',
+		),
+		'no_access' => 'Avètz pas accès sus %s',
+		'not_enabled' => '%s es pas encara activada',
+		'not_found' => '%s existís pas',
+	),
+	'import_export' => array(
+		'export_no_zip_extension' => 'L\'extension ZIP es pas presenta sul servidor. Volgatz ensajar d\'exportar los fichièrs un per un.',
+		'feeds_imported' => 'Vòstres fluxes son estats importats seràn actualizats en seguida',
+		'feeds_imported_with_errors' => 'Vòstres fluxes son estats importats mas i a agut d’errors',
+		'file_cannot_be_uploaded' => 'Telecargament del fichièr impossible',
+		'no_zip_extension' => 'L\'extension es pas presenta sul servidor.',
+		'zip_error' => 'Una error s’es producha pendent l’importacion del fichièr ZIP.',
+	),
+	'profile' => array(
+		'error' => 'Impossible d’actualizar vòstre perfil',
+		'updated' => 'Vòstre perfil es estat actualizat',
+	),
+	'sub' => array(
+		'actualize' => 'Actualizar',
+		'articles' => array(
+			'marked_read' => 'Los articles seleccionats son estats marcats coma legits.',
+			'marked_unread' => 'Los articles seleccionats son estats marcats coma pas legits.',
+		),
+		'category' => array(
+			'created' => 'La categoria « %s » es estada creada.',
+			'deleted' => 'La categoria es estada suprimida.',
+			'emptied' => 'La categoria es estada voidada',
+			'error' => 'Actualizacion de la categoria impossibla',
+			'name_exists' => 'Una categoria se ditz ja atal.',
+			'no_id' => 'Vos cal precisar l’id de la categoria.',
+			'no_name' => 'Vos cal donar un nom a la categoria.',
+			'not_delete_default' => 'Podètz pas suprimir la categoria per defaut !',
+			'not_exist' => 'Aquesta categoria existís pas !',
+			'over_max' => 'Avètz atengut la limita de categoria (%d)',
+			'updated' => 'La categoria es estada actualizada.',
+		),
+		'feed' => array(
+			'actualized' => '<em>%s</em> es a jorn',
+			'actualizeds' => 'Los fluxes son estats actualizats',
+			'added' => 'Lo flux RSS <em>%s</em> es ajustat',
+			'already_subscribed' => 'Seguissètz ja <em>%s</em>',
+			'deleted' => 'Lo flux es suprimit',
+			'error' => 'Error en actualizar',
+			'internal_problem' => 'Lo flux pòt pas èsser ajustat. <a href="%s">Consultatz los jornals d’audit de FreshRSS</a> per ne saber mai. Podètz forçar l’apondon  en ajustant <code>#force_feed</code> a l’URL.',
+			'invalid_url' => 'L\'URL <em>%s</em> es invalida',
+			'n_actualized' => '%s fluxes son estats actualizats',
+			'n_entries_deleted' => '%d articles son estats suprimits',
+			'no_refresh' => 'I a pas cap de flux d’actualizar…',
+			'not_added' => '<em>%s</em> a pas pogut èsser ajustat',
+			'over_max' => 'Avètz atengut vòstra limita de fluxes (%d)',
+			'updated' => 'Lo flux es actualizat',
+		),
+		'purge_completed' => 'Purga realizada (%s articles suprimits)',
+	),
+	'update' => array(
+		'can_apply' => 'FreshRSS es per èsser mes a jorn en <strong>version %s</strong>.',
+		'error' => 'La mesa a jorn a conegut un problèma : %s',
+		'file_is_nok' => 'Nòva <strong>version %s</strong> disponibla, mas volgatz verificar los dreches sul repertòri <em>%s</em>. Lo servidor HTTP deu poder escriure dedins',
+		'finished' => 'Mesa a jorn acabada !',
+		'none' => 'Cap de mesa a jorn d’aplicar',
+		'server_not_found' => 'Impossible de trobar lo servidor de mesa a jorn. [%s]',
+	),
+	'user' => array(
+		'created' => array(
+			'_' => 'L’utilizaire %s es estat creat',
+			'error' => 'L’utilizaire %s pòt pas èsser creat',
+		),
+		'deleted' => array(
+			'_' => 'L’utilizaire %s es estat suprimit',
+			'error' => 'L’utilizaire %s pòt pas èsser suprimit',
+		),
+		'updated' => array(
+			'_' => 'L’utilizaire %s es estat actualizat',
+			'error' => 'L’utilizaire %s es pas estat actualizat',
+		),
+	),
+);

+ 196 - 0
app/i18n/oc/gen.php

@@ -0,0 +1,196 @@
+<?php
+
+return array(
+	'action' => array(
+		'actualize' => 'Actualizar',
+		'back_to_rss_feeds' => '← Tornar a vòstres fluxes RSS',
+		'cancel' => 'Anullar',
+		'create' => 'Crear',
+		'disable' => 'Desactivar',
+		'empty' => 'Voidar',
+		'enable' => 'Activar',
+		'export' => 'Exportar',
+		'filter' => 'Filtre',
+		'import' => 'Importar',
+		'manage' => 'Gerir',
+		'mark_favorite' => 'Ajustar als favorits',
+		'mark_read' => 'Marcar coma legit',
+		'remove' => 'Levar',
+		'see_website' => 'Veire lo site',
+		'submit' => 'Mandar',
+		'truncate' => 'Suprimir totes los articles',
+		'update' => 'Actualizar',
+	),
+	'auth' => array(
+		'email' => 'Adreça de corrièl',
+		'keep_logged_in' => 'Demorar connectat <small>(%s jorns) </small>',
+		'login' => 'Connexion',
+		'logout' => 'Se desconnectar',
+		'password' => array(
+			'_' => 'Senhal',
+			'format' => '<small>Almens 7 caractèrs</small>',
+		),
+		'registration' => array(
+			'_' => 'Compte nòu',
+			'ask' => 'Crear un compte?',
+			'title' => 'Creacion de compte',
+		),
+		'reset' => 'Reïnicializacion de l’autentificacion',
+		'username' => array(
+			'_' => 'Nom d’utilizaire',
+			'admin' => 'Nom d’utilizaire administrator',
+			'format' => '<small>16 caractèrs alfanumerics maximum)</small>',
+		),
+	),
+	'date' => array(
+		'Apr' => 'a\b\r\i\a\l',
+		'apr' => 'abr.',
+		'april' => 'abrial',
+		'Aug' => 'a\g\o\s\t',
+		'aug' => 'agost',
+		'august' => 'agost',
+		'before_yesterday' => 'Abans ièr',
+		'Dec' => '\d\e\c\e\m\b\r\e',
+		'dec' => 'dec.',
+		'december' => 'decembre',
+		'Feb' => 'f\e\b\r\i\è\r',
+		'feb' => 'feb.',
+		'february' => 'febrièr',
+		'format_date' => 'j %s \de\ Y',
+		'format_date_hour' => 'j %s \de\ Y \a H\:i',
+		'fri' => 'dv',
+		'Jan' => 'g\e\n\i\è\r',
+		'jan' => 'gen.',
+		'january' => 'genièr',
+		'Jul' => 'j\u\l\h\e\t',
+		'jul' => 'julh',
+		'july' => 'julhet',
+		'Jun' => 'j\u\n\h',
+		'jun' => 'junh',
+		'june' => 'junh',
+		'last_3_month' => 'Dempuèi los tres darrièrs meses',
+		'last_6_month' => 'Dempuèi los sièis darrièrs meses',
+		'last_month' => 'Dempuèi lo mes passat',
+		'last_week' => 'Dempuèi la setmana passada',
+		'last_year' => 'Dempuèi l’annada passada',
+		'Mar' => 'm\a\r\ç',
+		'mar' => 'març',
+		'march' => 'març',
+		'May' => '\m\a\i',
+		'may' => 'mai',
+		'may_' => 'mai',
+		'mon' => 'dl',
+		'month' => 'meses',
+		'Nov' => '\n\o\v\e\m\b\r\e',
+		'nov' => 'nov.',
+		'november' => 'novembre',
+		'Oct' => '\o\c\t\ò\b\r\e',
+		'oct' => 'oct.',
+		'october' => 'octòbre',
+		'sat' => 'ds',
+		'Sep' => '\s\e\t\e\m\b\r\e',
+		'sep' => 'set.',
+		'september' => 'setembre',
+		'sun' => 'dg',
+		'thu' => 'dj',
+		'today' => 'Uèi',
+		'tue' => 'dm',
+		'wed' => 'Dc',
+		'yesterday' => 'Ièr',
+	),
+	'freshrss' => array(
+		'_' => 'FreshRSS',
+		'about' => 'A prepaus de FreshRSS',
+	),
+	'js' => array(
+		'category_empty' => 'Categoria voida',
+		'confirm_action' => 'Volètz vertadièrament contunhar ? Aquesta accion se pòt pas anullar !',
+		'confirm_action_feed_cat' => 'Volètz vertadièrament contunhar ? Perdretz los favorits e filtres ligats. Aquesta accion se pòt pas anullar !',
+		'feedback' => array(
+			'body_new_articles' => 'I a %%d nòus articles per legir sus FreshRSS.',
+			'request_failed' => 'Una requèsta a fach meuca, aquò pòt venir d’un problèma de connexion Internet.',
+			'title_new_articles' => 'FreshRSS : nòus articles !',
+		),
+		'new_article' => 'I a d’articles nòus disponibles, clicatz per actualizar la página.',
+		'should_be_activated' => 'JavaScript deu èsser activat',
+	),
+	'lang' => array(
+		'cz' => 'Čeština',
+		'de' => 'Deutsch',
+		'en' => 'English',
+		'es' => 'Español',
+		'fr' => 'Français',
+		'he' => 'עברית',
+		'it' => 'Italiano',
+		'kr' => '한국어',
+		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
+		'pt-br' => 'Português (Brasil)',
+		'ru' => 'Русский',
+		'tr' => 'Türkçe',
+		'zh-cn' => '简体中文',
+	),
+	'menu' => array(
+		'about' => 'A prepaus',
+		'admin' => 'Administracion',
+		'archiving' => 'Archivar',
+		'authentication' => 'Autentificacion',
+		'check_install' => 'Verificacion de l’installacion',
+		'configuration' => 'Configuracion',
+		'display' => 'Afichatge',
+		'extensions' => 'Extensions',
+		'logs' => 'Jornals d’audit',
+		'queries' => 'Filtres utilizaire',
+		'reading' => 'Lectura',
+		'search' => 'Recercar de mots o d’#etiquetas',
+		'sharing' => 'Partatge',
+		'shortcuts' => 'Acorchis',
+		'stats' => 'Estatisticas',
+		'system' => 'Configuracion sistèma',
+		'update' => 'Mesa a jorn',
+		'user_management' => 'Gestion dels utilizaires',
+		'user_profile' => 'Perfil',
+	),
+	'pagination' => array(
+		'first' => 'Debuta',
+		'last' => 'Fin',
+		'load_more' => 'Cargar mai d’articles',
+		'mark_all_read' => 'O marcar tot coma legit',
+		'next' => 'Seguent',
+		'nothing_to_load' => 'I a pas mai d’articles',
+		'previous' => 'Precedent',
+	),
+	'share' => array(
+		'blogotext' => 'Blogotext',
+		'diaspora' => 'Diaspora*',
+		'email' => 'Corrièl',
+		'facebook' => 'Facebook',
+		'g+' => 'Google+',
+		'gnusocial' => 'GNU social',
+		'jdh' => 'Journal du hacker',
+		'Known' => 'Sites basats sus Known',
+		'linkedin' => 'LinkedIn',
+		'mastodon' => 'Mastodon',
+		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
+		'pocket' => 'Pocket',
+		'print' => 'Imprimir',
+		'shaarli' => 'Shaarli',
+		'twitter' => 'Twitter',
+		'wallabag' => 'wallabag v1',
+		'wallabagv2' => 'wallabag v2',
+	),
+	'short' => array(
+		'attention' => 'Atencion !',
+		'blank_to_disable' => 'Daissar void per desactivar',
+		'by_author' => 'Per <em>%s</em>',
+		'by_default' => 'Per defaut',
+		'damn' => 'Zut !',
+		'default_category' => 'Pas triat',
+		'no' => 'Non',
+		'not_applicable' => 'Pas disponible',
+		'ok' => 'Òc-ben !',
+		'or' => 'o',
+		'yes' => 'Òc',
+	),
+);

+ 63 - 0
app/i18n/oc/index.php

@@ -0,0 +1,63 @@
+<?php
+
+return array(
+	'about' => array(
+		'_' => 'A prepaus',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'bugs_reports' => 'Senhalament de problèmas',
+		'credits' => 'Crèdits',
+		'credits_content' => 'Unes elements de l’estil venon del <a href="http://twitter.github.io/bootstrap/">projècte Bootstrap</a> encara que FreshRSS utilize pas aqueste framework. Las<a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icònas</a> venon del <a href="https://www.gnome.org/">projècte GNOME</a>. La polissa <em>Open Sans</em> utilizada foguèt creada per en <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS es basat sus <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.',
+		'freshrss_description' => 'FreshRSS es un agregador de fluxes RSS per l’auto-albergar tal coma <a href="http://tontof.net/kriss/feed/">Kriss Feed</a> o <a href="http://projet.idleman.fr/leed/">Leed</a>. Sa tòca es d’èsser leugièr e de bon utilizar de prima abòrd mas tanben d’èsser potent e parametrable.',
+		'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">on Github</a>',
+		'license' => 'Licéncia',
+		'project_website' => 'Site del projècte',
+		'title' => 'A prepaus',
+		'website' => 'Site internet',
+		'version' => 'Version',
+	),
+	'feed' => array(
+		'add' => 'Podètz ajustar de fluxes.',
+		'empty' => 'I a pas cap de flux de mostrar.',
+		'rss_of' => 'Flux RSS de %s',
+		'title' => 'Vòstres fluxes RSS',
+		'title_global' => 'Vista generala',
+		'title_fav' => 'Vòstres favorits',
+	),
+	'log' => array(
+		'_' => 'Jornals d’audit',
+		'clear' => 'Escafar los jornals',
+		'empty' => 'Los jornals son voids',
+		'title' => 'Jornals d’audit',
+	),
+	'menu' => array(
+		'about' => 'A prepaus de FreshRSS',
+		'add_query' => 'Crear un filtre',
+		'before_one_day' => '1 jorn en arrièr',
+		'before_one_week' => '1 setmana en arrièr',
+		'favorites' => 'Favorits (%s)',
+		'global_view' => 'Vista generala',
+		'main_stream' => 'Flux màger',
+		'mark_all_read' => 'O marcar tot coma legit',
+		'mark_cat_read' => 'Marcar la categoria coma legida',
+		'mark_feed_read' => 'Marcar lo flux coma legit',
+		'mark_selection_unread' => 'Marcar la seleccion coma pas legida',
+		'newer_first' => 'Mai recents en primièr',
+		'non-starred' => 'Mostrar los pas favorits',
+		'normal_view' => 'Vista normala',
+		'older_first' => 'Mai ancians en primièr',
+		'queries' => 'Filtres utilizaire',
+		'read' => 'Mostrar los legits',
+		'reader_view' => 'Vista lectura',
+		'rss_view' => 'Flux RSS',
+		'search_short' => 'Recercar',
+		'starred' => 'Mostrar los favorits',
+		'stats' => 'Estatisticas',
+		'subscription' => 'Gestion dels abonaments',
+		'tags' => 'Mas etiquetas',
+		'unread' => 'Mostar los pas legits',
+	),
+	'share' => 'Partejar',
+	'tag' => array(
+		'related' => 'Etiquetas ligadas',
+	),
+);

+ 123 - 0
app/i18n/oc/install.php

@@ -0,0 +1,123 @@
+<?php
+
+return array(
+	'action' => array(
+		'finish' => 'Acabar l’installacion',
+		'fix_errors_before' => 'Mercés de corregir las errors seguentas abans de contunhar.',
+		'keep_install' => 'Gardar la configuracion precedenta',
+		'next_step' => 'Anar a l’estapa seguenta',
+		'reinstall' => 'Reïnstallar FreshRSS',
+	),
+	'auth' => array(
+		'form' => 'Formulari (tradicional, demanda JavaScript)',
+		'http' => 'HTTP (per utilizaires avançats amb HTTPS)',
+		'none' => 'Cap (perilhós)',
+		'password_form' => 'Senhal API<br /><small>(ex. : per la connexion via formulari)</small>',
+		'password_format' => 'Almens 7 caractèrs',
+		'type' => 'Mòde d’autentification',
+	),
+	'bdd' => array(
+		'_' => 'Basa de donadas',
+		'conf' => array(
+			'_' => 'Configuracion de la basa de donadas',
+			'ko' => 'Verificatz las informacions de la basa de donadas.',
+			'ok' => 'La configuracion de la basa de donadas es salvagarda.',
+		),
+		'host' => 'Òste',
+		'password' => 'Senhal de la basa de donadas',
+		'prefix' => 'Prefixe de tabla',
+		'type' => 'Tipe de basa de donadas',
+		'username' => 'Nom d’utilizaire de la basa de donadas',
+	),
+	'check' => array(
+		'_' => 'Verificacions',
+		'already_installed' => 'Sembla que FreshRSS es ja installat !',
+		'cache' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data/cache</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul cache son bons.',
+		),
+		'ctype' => array(
+			'nok' => 'Impossible de trobar una bibliotèca per la verificacion del tipe de caractèrs (php-ctype).',
+			'ok' => 'Avètz la bibliotèca per la verificacion del tipe de caractèrs (ctype).',
+		),
+		'curl' => array(
+			'nok' => 'Impossible de trobar la bibliotèca curl ( paquet php-curl).',
+			'ok' => 'Avètz la bibliotèca cURL.',
+		),
+		'data' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul repertòri data son bons.',
+		),
+		'dom' => array(
+			'nok' => 'Impossible de trobar una bibliotèca per percórrer lo DOM.',
+			'ok' => 'Avètz la bibliotèca per percórrer lo DOM.',
+		),
+		'favicons' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data/favicons</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul repertòri dels favicons son bons.',
+		),
+		'fileinfo' => array(
+			'nok' => 'Avètz pas PHP fileinfo (paquet fileinfo).',
+			'ok' => 'Avètz la bibliotèca fileinfo.',
+		),
+		'http_referer' => array(
+			'nok' => 'Mercés de verificar que modificatz pas vòstre HTTP REFERER.',
+			'ok' => 'Lo HTTP REFERER es conegut e sembla correspondre a vòstre servidor.',
+		),
+		'json' => array(
+			'nok' => 'Impossible de trobar l’extension recomandada JSON (paquet php-json).',
+			'ok' => 'Avètz l’exension recomandada JSON.',
+		),
+		'mbstring' => array(
+			'nok' => 'Impossible de trobar la bibliotèca recomandada mbstring per Unicode.',
+			'ok' => 'Avètz la bibliotèca recomandada mbstring per Unicode.',
+		),
+		'minz' => array(
+			'nok' => 'Avètz pas la bibliotèca Minz.',
+			'ok' => 'Avètz la bibliotèca Minz.',
+		),
+		'pcre' => array(
+			'nok' => 'Impossible de trobar una bibliotèca per las expressions regulara (php-pcre).',
+			'ok' => 'Avètz la bibliotèca per las expressions regularas (PCRE).',
+		),
+		'pdo' => array(
+			'nok' => 'Impossible de trobar PDO o un dels drivers compatibles (pdo_mysql, pdo_sqlite, pdo_pgsql).',
+			'ok' => 'Avètz PDO e almens un des drivers compatibles (pdo_mysql, pdo_sqlite, pdo_pgsql).',
+		),
+		'php' => array(
+			'nok' => 'Vòstra version PHP es la %s mas FreshRSS demanda almens la version %s.',
+			'ok' => 'Vòstra version PHP es %s, qu’es compatibla amb FreshRSS.',
+		),
+		'users' => array(
+			'nok' => 'Volgatz verificar los dreches sul repertòri <em>./data/users</em>. Lo servidor HTTP deu poder escriure dedins',
+			'ok' => 'Los dreches sul repertòri dels utilizaires son bons.',
+		),
+		'xml' => array(
+			'nok' => 'Impossible de trobar una bibliotèca necessària per XML.',
+			'ok' => 'Avètz la bibliotèca per percórrer los XML.',
+		),
+	),
+	'conf' => array(
+		'_' => 'Configuracion generala',
+		'ok' => 'La configuracion generala es enregistrada.',
+	),
+	'congratulations' => 'Òsca !',
+	'default_user' => 'Nom d’utilizaire per defaut <small>16 caractèrs alfanumerics maximum)</small>',
+	'delete_articles_after' => 'Levar los articles aprèp',
+	'fix_errors_before' => 'Mercés de corregir las errors seguentas abans de contunhar.',
+	'javascript_is_better' => 'FreshRSS es mai agradable amb lo JavaScript activat',
+	'js' => array(
+		'confirm_reinstall' => 'En reïnstallant FreshRSS perdretz la configuracion precedenta. Volètz vertadièrament contunhar ?',
+	),
+	'language' => array(
+		'_' => 'Lenga',
+		'choose' => 'Causissètz la lenga per FreshRSS',
+		'defined' => 'La lenga es corrèctament definida.',
+	),
+	'not_deleted' => 'Quicòm a trucat, sembla qu’avètz suprimit <em>%s</em> a la man.',
+	'ok' => 'L’installacion s’es corrèctament passada.',
+	'step' => 'etapa %d',
+	'steps' => 'Etapas',
+	'title' => 'Installacion · FreshRSS',
+	'this_is_the_end' => 'Es la fin',
+);

+ 93 - 0
app/i18n/oc/sub.php

@@ -0,0 +1,93 @@
+<?php
+return array(
+	'api' => array(
+		'documentation' => 'Copiar l’URL seguenta per l’utilizaire dins d’una aisina extèrna.',
+		'title' => 'API',
+	),
+	'bookmarklet' => array(
+		'documentation' => 'Depausatz aqueste boton per la barra de marcapaginas o clicatz-lo a drecha e causissètz « Enregistrar aqueste ligam». Puèi clicatz «S’abonar» sus las paginas que volètz seguir.',
+		'label' => 'S’abonar',
+		'title' => 'Bookmarklet',
+	),
+	'category' => array(
+		'_' => 'Categoria',
+		'add' => 'Ajustar una categoria',
+		'empty' => 'Categoria voida',
+		'new' => 'Nòva categoria',
+	),
+	'feed' => array(
+		'add' => 'Ajustar un flux RSS',
+		'advanced' => 'Avançat',
+		'archiving' => 'Archivar',
+		'auth' => array(
+			'configuration' => 'Identificacion',
+			'help' => 'Permet l’accès als fluxes protegits per una autentificacion HTTP',
+			'http' => 'Autentificacion HTTP',
+			'password' => 'Senhal HTTP',
+			'username' => 'Identificant HTTP',
+		),
+		'clear_cache' => 'Totjorn escafar lo cache',
+		'css_help' => 'Permet de recuperar los fluxes troncats (atencion, demanda mai de temps !)',
+		'css_path' => 'Selector CSS dels articles sul site d’origina',
+		'description' => 'Descripcion',
+		'empty' => 'Aqueste flux es void. Assegurats-vos qu’es totjorn mantengut.',
+		'error' => 'Aqueste flux a rescontrat un problèma. Volgatz verificar que siá totjorn accessible puèi actualizatz-lo.',
+		'informations' => 'Informacions',
+		'keep_history' => 'Nombre minimum d’articles de servar',
+		'moved_category_deleted' => 'Quand escafatz una categoria, sos fluxes son automaticament classats dins <em>%s</em>.',
+		'mute' => 'mut',
+		'no_selected' => 'Cap de flux pas seleccionat.',
+		'number_entries' => '%d articles',
+		'priority' => array(
+			'_' => 'Visibilitat',
+			'archived' => 'Mostrar pas (archivat)',
+			'main_stream' => 'Mostar al flux màger',
+			'normal' => 'Mostar dins sa categoria',
+		),
+		'websub' => 'Notificaciones instantáneas amb WebSub',
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
+		'ssl_verify' => 'Verificacion de la seguretat SSL',
+		'stats' => 'Estatisticas',
+		'think_to_add' => 'Podètz ajustar de fluxes.',
+		'timeout' => 'Temps d’espèra en segondas',
+		'title' => 'Títol',
+		'title_add' => 'Ajustar un flux RSS',
+		'ttl' => 'Actualizar pas automaticament mai sovent que',
+		'url' => 'Flux URL',
+		'validator' => 'Verificar la validitat del flux',
+		'website' => 'URL del site',
+	),
+	'firefox' => array(
+		'documentation' => 'Seguir las etapas descrichas <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">aquí</a> per ajustar FreshRSS a la lista dels lectors de flux de Firefox.',
+		'title' => 'Lector de flux de Firefox',
+	),
+	'import_export' => array(
+		'export' => 'Exportar',
+		'export_opml' => 'Exportar la lista de fluxes (OPML)',
+		'export_starred' => 'Exportar los favorits',
+		'feed_list' => 'Lista dels %s articles',
+		'file_to_import' => 'Fichièr d’importar<br />(OPML, JSON o ZIP)',
+		'file_to_import_no_zip' => 'Fichièr d’importar<br />(OPML o JSON)',
+		'import' => 'Importar',
+		'starred_list' => 'Lista dels articles favorits',
+		'title' => 'Importar / Exportar',
+
+	),
+	'menu' => array(
+		'bookmark' => 'Sabonar (marcapagina FreshRSS)',
+		'import_export' => 'Importar / Exportar',
+		'subscription_management' => 'Gestion dels abonaments',
+		'subscription_tools' => 'Aisinas d’abonament',
+	),
+	'title' => array(
+		'_' => 'Gestión dels abonaments',
+		'feed_management' => 'Gestion dels fluxes RSS',
+		'subscription_tools' => 'Aisinas d’abonament',
+	),
+);

+ 16 - 12
app/i18n/pt-br/admin.php

@@ -67,8 +67,8 @@ return array(
 			'ok' => 'Você tem a extensão JSON.',
 			'ok' => 'Você tem a extensão JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Não foi possível encontrar o framework Minz.',
 			'nok' => 'Não foi possível encontrar o framework Minz.',
@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Author',	//TODO - Translation
+		'community' => 'Available community extensions',	//TODO - Translation
+		'description' => 'Description',	//TODO - Translation
 		'disabled' => 'Desabilitado',
 		'disabled' => 'Desabilitado',
 		'empty_list' => 'Não há extensões instaladas',
 		'empty_list' => 'Não há extensões instaladas',
 		'enabled' => 'Habilitada',
 		'enabled' => 'Habilitada',
+		'latest' => 'Installed',	//TODO - Translation
+		'name' => 'Name',	//TODO - Translation
 		'no_configure_view' => 'Esta extensão não pode ser configurada.',
 		'no_configure_view' => 'Esta extensão não pode ser configurada.',
 		'system' => array(
 		'system' => array(
 			'_' => 'Extensões do sistema',
 			'_' => 'Extensões do sistema',
 			'no_rights' => 'Extensões do sistema (Você não tem direitos para isto)',
 			'no_rights' => 'Extensões do sistema (Você não tem direitos para isto)',
 		),
 		),
 		'title' => 'Extensões',
 		'title' => 'Extensões',
+		'update' => 'Update available',	//TODO - Translation
 		'user' => 'Extensões do usuário',
 		'user' => 'Extensões do usuário',
-		'community' => 'Available community extensions', // @todo translate
-		'name' => 'Name', // @todo translate
-		'version' => 'Version', // @todo translate
-		'description' => 'Description', // @todo translate
-		'author' => 'Author', // @todo translate
-		'latest' => 'Installed', // @todo translate
-		'update' => 'Update available', // @todo translate
+		'version' => 'Version',	//TODO - Translation
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Estatísticas',
 		'_' => 'Estatísticas',
@@ -162,6 +162,10 @@ return array(
 		'instance-name' => 'Nome da instância',
 		'instance-name' => 'Nome da instância',
 		'max-categories' => 'Limite de categorias por usuário',
 		'max-categories' => 'Limite de categorias por usuário',
 		'max-feeds' => 'Limite de Feeds por usuário',
 		'max-feeds' => 'Limite de Feeds por usuário',
+		'cookie-duration' => array(
+			'help' => 'in seconds', // @todo translate
+			'number' => 'Duration to keep logged in', // @todo translate
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 significa que não há limite para a conta',
 			'help' => '0 significa que não há limite para a conta',
 			'number' => 'Máximo número de contas',
 			'number' => 'Máximo número de contas',
@@ -179,15 +183,15 @@ return array(
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s artigos (%s)',
 		'articles_and_size' => '%s artigos (%s)',
 		'create' => 'Criar novo usuário',
 		'create' => 'Criar novo usuário',
-		'delete_users' => 'Delete user', // TODO
+		'delete_users' => 'Delete user',	//TODO - Translation
 		'language' => 'Idioma',
 		'language' => 'Idioma',
 		'number' => 'Há %d conta criada',
 		'number' => 'Há %d conta criada',
 		'numbers' => 'Há %d contas criadas',
 		'numbers' => 'Há %d contas criadas',
 		'password_form' => 'Senha<br /><small>(para o login pelo método do formulário)</small>',
 		'password_form' => 'Senha<br /><small>(para o login pelo método do formulário)</small>',
 		'password_format' => 'Ao menos 7 caracteres',
 		'password_format' => 'Ao menos 7 caracteres',
-		'selected' => 'Selected user', // TODO
+		'selected' => 'Selected user',	//TODO - Translation
 		'title' => 'Gerenciar usuários',
 		'title' => 'Gerenciar usuários',
-		'update_users' => 'Update user', // TODO
+		'update_users' => 'Update user',	//TODO - Translation
 		'user_list' => 'Lista de usuários',
 		'user_list' => 'Lista de usuários',
 		'username' => 'Usuário',
 		'username' => 'Usuário',
 		'users' => 'Usuários',
 		'users' => 'Usuários',

+ 28 - 25
app/i18n/pt-br/conf.php

@@ -19,7 +19,7 @@ return array(
 			'bottom_line' => 'Linha inferior',
 			'bottom_line' => 'Linha inferior',
 			'entry' => 'Ícones de artigos',
 			'entry' => 'Ícones de artigos',
 			'publication_date' => 'Data da publicação',
 			'publication_date' => 'Data da publicação',
-			'related_tags' => 'Tags relacionadas',	//TODO
+			'related_tags' => 'Tags relacionadas',	//TODO - Translation
 			'sharing' => 'Compartilhar',
 			'sharing' => 'Compartilhar',
 			'top_line' => 'Linha superior',
 			'top_line' => 'Linha superior',
 		),
 		),
@@ -28,6 +28,7 @@ return array(
 			'seconds' => 'segundos (0 significa sem timeout)',
 			'seconds' => 'segundos (0 significa sem timeout)',
 			'timeout' => 'Notificação em HTML5 de timeout',
 			'timeout' => 'Notificação em HTML5 de timeout',
 		),
 		),
+		'show_nav_buttons' => 'Show the navigation buttons',	//TODO - Translation
 		'theme' => 'Tema',
 		'theme' => 'Tema',
 		'title' => 'Exibição',
 		'title' => 'Exibição',
 		'width' => array(
 		'width' => array(
@@ -37,12 +38,22 @@ return array(
 			'no_limit' => 'Sem lmite',
 			'no_limit' => 'Sem lmite',
 			'thin' => 'Fino',
 			'thin' => 'Fino',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	//TODO
+	),
+	'profile' => array(
+		'_' => 'Gerenciamento de perfil',
+		'delete' => array(
+			'_' => 'Remover conta',
+			'warn' => 'Sua conta e todos os dados relacionados serão removidos.',
+		),
+		'password_api' => 'Senha da API<br /><small>(p.s., para aplicativos móveis)</small>',
+		'password_form' => 'Senha<br /><small>(para o método de formulário web)</small>',
+		'password_format' => 'Ao menos 7 caracteres',
+		'title' => 'Perfil',
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'Queries do usuário',
 		'_' => 'Queries do usuário',
 		'deprecated' => 'Esta não é mais válida. A categoria ou feed relacionado foi deletado.',
 		'deprecated' => 'Esta não é mais válida. A categoria ou feed relacionado foi deletado.',
-		'display' => 'Display user query results', // TODO
+		'display' => 'Display user query results',	//TODO - Translation
 		'filter' => 'Filtro aplicado:',
 		'filter' => 'Filtro aplicado:',
 		'get_all' => 'Mostrar todos os artigos',
 		'get_all' => 'Mostrar todos os artigos',
 		'get_category' => 'Visualizar "%s" categoria',
 		'get_category' => 'Visualizar "%s" categoria',
@@ -53,7 +64,7 @@ return array(
 		'number' => 'Query n°%d',
 		'number' => 'Query n°%d',
 		'order_asc' => 'Exibir artigos mais antigos primeiro',
 		'order_asc' => 'Exibir artigos mais antigos primeiro',
 		'order_desc' => 'Exibir artigos mais novos primeiro',
 		'order_desc' => 'Exibir artigos mais novos primeiro',
-		'remove' => 'Remove user query', // TODO
+		'remove' => 'Remove user query',	//TODO - Translation
 		'search' => 'Busca por "%s"',
 		'search' => 'Busca por "%s"',
 		'state_0' => 'Exibir todos os artigos',
 		'state_0' => 'Exibir todos os artigos',
 		'state_1' => 'Exibir artigos lidos',
 		'state_1' => 'Exibir artigos lidos',
@@ -73,31 +84,19 @@ return array(
 		'state_15' => 'Exibir todos os artigos',
 		'state_15' => 'Exibir todos os artigos',
 		'title' => 'Queries de usuários',
 		'title' => 'Queries de usuários',
 	),
 	),
-	'profile' => array(
-		'_' => 'Gerenciamento de perfil',
-		'delete' => array(
-			'_' => 'Remover conta',
-			'warn' => 'Sua conta e todos os dados relacionados serão removidos.',
-		),
-		'password_api' => 'Senha da API<br /><small>(p.s., para aplicativos móveis)</small>',
-		'password_form' => 'Senha<br /><small>(para o método de formulário web)</small>',
-		'password_format' => 'Ao menos 7 caracteres',
-		'title' => 'Perfil',
-	),
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Leitura',
 		'_' => 'Leitura',
 		'after_onread' => 'Depois de "marcar todos como lido",',
 		'after_onread' => 'Depois de "marcar todos como lido",',
 		'articles_per_page' => 'Número de artigos por página',
 		'articles_per_page' => 'Número de artigos por página',
 		'auto_load_more' => 'Carregar mais artigos no final da página',
 		'auto_load_more' => 'Carregar mais artigos no final da página',
 		'auto_remove_article' => 'Esconder artigos depois de lidos',
 		'auto_remove_article' => 'Esconder artigos depois de lidos',
-		'mark_updated_article_unread' => 'Marcar artigos atualizados como não lidos',
 		'confirm_enabled' => 'Exibir uma caixa de diálogo de confirmação quando acionar "marcar todos como lido"',
 		'confirm_enabled' => 'Exibir uma caixa de diálogo de confirmação quando acionar "marcar todos como lido"',
 		'display_articles_unfolded' => 'Mostrar aritogs abertos por padrão',
 		'display_articles_unfolded' => 'Mostrar aritogs abertos por padrão',
 		'display_categories_unfolded' => 'Mostrar artigos fechados por padrão',
 		'display_categories_unfolded' => 'Mostrar artigos fechados por padrão',
 		'hide_read_feeds' => 'Esconder categorias e feeds com nenhum artigo não lido (não funciona com a configuração "Mostrar todos os artigos”)',
 		'hide_read_feeds' => 'Esconder categorias e feeds com nenhum artigo não lido (não funciona com a configuração "Mostrar todos os artigos”)',
 		'img_with_lazyload' => 'Utilizar o modo "lazy load" para carregar as imagens',
 		'img_with_lazyload' => 'Utilizar o modo "lazy load" para carregar as imagens',
-		'sides_close_article' => 'Clicando fora da área do texto do artigo fecha o mesmo',
 		'jump_next' => 'Vá para o próximo irmão não lido (feed ou categoria)',
 		'jump_next' => 'Vá para o próximo irmão não lido (feed ou categoria)',
+		'mark_updated_article_unread' => 'Marcar artigos atualizados como não lidos',
 		'number_divided_when_reader' => 'Dividido por 2 no modo de leitura .',
 		'number_divided_when_reader' => 'Dividido por 2 no modo de leitura .',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'quando o artigo é aberto no site original',
 			'article_open_on_website' => 'quando o artigo é aberto no site original',
@@ -112,6 +111,7 @@ return array(
 			'all_articles' => 'Exibir todos os artigos',
 			'all_articles' => 'Exibir todos os artigos',
 			'unread' => 'Exibir apenas não lido',
 			'unread' => 'Exibir apenas não lido',
 		),
 		),
+		'sides_close_article' => 'Clicando fora da área do texto do artigo fecha o mesmo',
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Ordem de visualização',
 			'_' => 'Ordem de visualização',
 			'newer_first' => 'Novos primeiro',
 			'newer_first' => 'Novos primeiro',
@@ -128,7 +128,7 @@ return array(
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Compartilhando',
 		'_' => 'Compartilhando',
-		'add' => 'Add a sharing method', // TODO
+		'add' => 'Add a sharing method',	//TODO - Translation
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -136,7 +136,7 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'more_information' => 'Mais informação',
 		'more_information' => 'Mais informação',
 		'print' => 'Imprimir',
 		'print' => 'Imprimir',
-		'remove' => 'Remove sharing method', // TODO
+		'remove' => 'Remove sharing method',	//TODO - Translation
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
 		'share_name' => 'Nome de visualização para compartilhar',
 		'share_name' => 'Nome de visualização para compartilhar',
 		'share_url' => 'URL utilizada para compartilhar',
 		'share_url' => 'URL utilizada para compartilhar',
@@ -153,27 +153,30 @@ return array(
 		'collapse_article' => 'Fechar',
 		'collapse_article' => 'Fechar',
 		'first_article' => 'Ir para o primeiro artigo',
 		'first_article' => 'Ir para o primeiro artigo',
 		'focus_search' => 'Acessar a caixa de busca',
 		'focus_search' => 'Acessar a caixa de busca',
-		'global_view' => 'Switch to global view', // TODO
+		'global_view' => 'Switch to global view',	//TODO - Translation
 		'help' => 'Mostrar documentação',
 		'help' => 'Mostrar documentação',
 		'javascript' => 'JavaScript deve ser habilitado para utilizar atalhos',
 		'javascript' => 'JavaScript deve ser habilitado para utilizar atalhos',
 		'last_article' => 'Ir para o último artigo',
 		'last_article' => 'Ir para o último artigo',
 		'load_more' => 'Carregar mais artigos',
 		'load_more' => 'Carregar mais artigos',
-		'mark_read' => 'Marcar como lido',
 		'mark_favorite' => 'Marcar como favorito',
 		'mark_favorite' => 'Marcar como favorito',
+		'mark_read' => 'Marcar como lido',
 		'navigation' => 'Navegação',
 		'navigation' => 'Navegação',
 		'navigation_help' => 'Com o modificador "Shift", atalhos de navegação aplicam aos feeds.<br/>Com o "Alt" modificador, atalhos de navegação aplicam as categorias.',
 		'navigation_help' => 'Com o modificador "Shift", atalhos de navegação aplicam aos feeds.<br/>Com o "Alt" modificador, atalhos de navegação aplicam as categorias.',
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
 		'next_article' => 'Pule para o próximo artigo',
 		'next_article' => 'Pule para o próximo artigo',
-		'normal_view' => 'Switch to normal view', // TODO
+		'normal_view' => 'Switch to normal view',	//TODO - Translation
 		'other_action' => 'Outras ações',
 		'other_action' => 'Outras ações',
 		'previous_article' => 'Pule para o artigo anterior',
 		'previous_article' => 'Pule para o artigo anterior',
-		'reading_view' => 'Switch to reading view', // TODO
-		'rss_view' => 'Open RSS view in a new tab', // TODO
+		'reading_view' => 'Switch to reading view',	//TODO - Translation
+		'rss_view' => 'Open RSS view in a new tab',	//TODO - Translation
 		'see_on_website' => 'Visualize o site original',
 		'see_on_website' => 'Visualize o site original',
 		'shift_for_all_read' => '+ <code>shift</code> para marcar todos os artigos como lido',
 		'shift_for_all_read' => '+ <code>shift</code> para marcar todos os artigos como lido',
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
 		'title' => 'Atalhos',
 		'title' => 'Atalhos',
 		'user_filter' => 'Acesse filtros de usuário',
 		'user_filter' => 'Acesse filtros de usuário',
 		'user_filter_help' => 'Se há apenas um filtro, ele é utilizado. Caso contrário, os filtros serão acessíveis pelos seus números.',
 		'user_filter_help' => 'Se há apenas um filtro, ele é utilizado. Caso contrário, os filtros serão acessíveis pelos seus números.',
-		'views' => 'Views', // TODO
+		'views' => 'Views',	//TODO - Translation
 	),
 	),
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s artigos (%s)',
 		'articles_and_size' => '%s artigos (%s)',

+ 9 - 9
app/i18n/pt-br/feedback.php

@@ -50,11 +50,15 @@ return array(
 		'no_zip_extension' => 'extensão ZIP não está presente em seu servidor.',
 		'no_zip_extension' => 'extensão ZIP não está presente em seu servidor.',
 		'zip_error' => 'Um erro ocorreu durante a importação do arquivo ZIP.',
 		'zip_error' => 'Um erro ocorreu durante a importação do arquivo ZIP.',
 	),
 	),
+	'profile' => array(
+		'error' => 'Your profile cannot be modified',
+		'updated' => 'Your profile has been modified',
+	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Atualizando',
 		'actualize' => 'Atualizando',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	//TODO
-			'marked_unread' => 'The articles have been marked as unread.',	//TODO
+			'marked_read' => 'The selected articles have been marked as read.',	//TODO - Translation
+			'marked_unread' => 'The articles have been marked as unread.',	//TODO - Translation
 		),
 		),
 		'category' => array(
 		'category' => array(
 			'created' => 'Categoria %s foi criada.',
 			'created' => 'Categoria %s foi criada.',
@@ -76,7 +80,7 @@ return array(
 			'already_subscribed' => 'Você já está inscrito no <em>%s</em>',
 			'already_subscribed' => 'Você já está inscrito no <em>%s</em>',
 			'deleted' => 'o Feed foi deletado',
 			'deleted' => 'o Feed foi deletado',
 			'error' => 'O feed não pode ser atualizado',
 			'error' => 'O feed não pode ser atualizado',
-			'internal_problem' => 'O RSS feed não pôde ser adicionado. <a href="%s">Verifique os FreshRSS logs</a> para detalhes.', // @todo
+			'internal_problem' => 'O RSS feed não pôde ser adicionado. <a href="%s">Verifique os FreshRSS logs</a> para detalhes.',	//TODO - Translation
 			'invalid_url' => 'URL <em>%s</em> é inválida',
 			'invalid_url' => 'URL <em>%s</em> é inválida',
 			'n_actualized' => '%d feeds foram atualizados',
 			'n_actualized' => '%d feeds foram atualizados',
 			'n_entries_deleted' => '%d artigos foram deletados',
 			'n_entries_deleted' => '%d artigos foram deletados',
@@ -105,12 +109,8 @@ return array(
 			'error' => 'Usuário %s não pode ser deletado',
 			'error' => 'Usuário %s não pode ser deletado',
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated', // TODO
-			'error' => 'User %s has not been updated', // TODO
+			'_' => 'User %s has been updated',	//TODO - Translation
+			'error' => 'User %s has not been updated',	//TODO - Translation
 		),
 		),
 	),
 	),
-	'profile' => array(
-		'error' => 'Your profile cannot be modified',
-		'updated' => 'Your profile has been modified',
-	),
 );
 );

+ 16 - 13
app/i18n/pt-br/gen.php

@@ -19,7 +19,7 @@ return array(
 		'see_website' => 'Ver o site',
 		'see_website' => 'Ver o site',
 		'submit' => 'Enviar',
 		'submit' => 'Enviar',
 		'truncate' => 'Deletar todos os artigos',
 		'truncate' => 'Deletar todos os artigos',
-		'update' => 'Update', // TODO
+		'update' => 'Update',	//TODO - Translation
 	),
 	),
 	'auth' => array(
 	'auth' => array(
 		'email' => 'Endereço de e-mail',
 		'email' => 'Endereço de e-mail',
@@ -44,33 +44,28 @@ return array(
 	),
 	),
 	'date' => array(
 	'date' => array(
 		'Apr' => '\\A\\b\\r\\i\\l',
 		'Apr' => '\\A\\b\\r\\i\\l',
-		'Aug' => '\\A\\g\\o\\s\\t\\o',
-		'Dec' => '\\D\\e\\z\\e\\m\\b\\r\\o',
-		'Feb' => '\\F\\e\\v\\e\\r\\e\\i\\r\\o',
-		'Jan' => '\\J\\a\\n\\e\\i\\r\\o',
-		'Jul' => '\\J\\u\\l\\h\\o',
-		'Jun' => '\\J\\u\\n\\h\\o',
-		'Mar' => '\\M\\a\\r\\ç\\o',
-		'May' => '\\M\\a\\i\\o',
-		'Nov' => '\\N\\o\\v\\e\\m\\b\\r\\o',
-		'Oct' => '\\O\\u\\t\\u\\b\\r\\o',
-		'Sep' => '\\S\\e\\t\\e\\m\\b\\r\\o',
 		'apr' => 'abr',
 		'apr' => 'abr',
 		'april' => 'Abr',
 		'april' => 'Abr',
+		'Aug' => '\\A\\g\\o\\s\\t\\o',
 		'aug' => 'ago',
 		'aug' => 'ago',
 		'august' => 'Ago',
 		'august' => 'Ago',
 		'before_yesterday' => 'Antes de ontem',
 		'before_yesterday' => 'Antes de ontem',
+		'Dec' => '\\D\\e\\z\\e\\m\\b\\r\\o',
 		'dec' => 'dez',
 		'dec' => 'dez',
 		'december' => 'Dez',
 		'december' => 'Dez',
+		'Feb' => '\\F\\e\\v\\e\\r\\e\\i\\r\\o',
 		'feb' => 'fev',
 		'feb' => 'fev',
 		'february' => 'Fev',
 		'february' => 'Fev',
 		'format_date' => 'j \\d\\e %s \\d\\e Y',
 		'format_date' => 'j \\d\\e %s \\d\\e Y',
 		'format_date_hour' => 'j \\d\\e %s \\d\\e Y\\, H\\:i',
 		'format_date_hour' => 'j \\d\\e %s \\d\\e Y\\, H\\:i',
 		'fri' => 'Sex',
 		'fri' => 'Sex',
+		'Jan' => '\\J\\a\\n\\e\\i\\r\\o',
 		'jan' => 'jan',
 		'jan' => 'jan',
 		'january' => 'Jan',
 		'january' => 'Jan',
+		'Jul' => '\\J\\u\\l\\h\\o',
 		'jul' => 'jul',
 		'jul' => 'jul',
 		'july' => 'Jul',
 		'july' => 'Jul',
+		'Jun' => '\\J\\u\\n\\h\\o',
 		'jun' => 'jun',
 		'jun' => 'jun',
 		'june' => 'Jun',
 		'june' => 'Jun',
 		'last_3_month' => 'Últimos três meses',
 		'last_3_month' => 'Últimos três meses',
@@ -78,16 +73,22 @@ return array(
 		'last_month' => 'Últimos mês',
 		'last_month' => 'Últimos mês',
 		'last_week' => 'Última semana',
 		'last_week' => 'Última semana',
 		'last_year' => 'Último ano',
 		'last_year' => 'Último ano',
+		'Mar' => '\\M\\a\\r\\ç\\o',
 		'mar' => 'mar',
 		'mar' => 'mar',
 		'march' => 'Mar',
 		'march' => 'Mar',
+		'May' => '\\M\\a\\i\\o',
 		'may' => 'Mai',
 		'may' => 'Mai',
+		'may_' => 'Mai',
 		'mon' => 'Seg',
 		'mon' => 'Seg',
 		'month' => 'meses',
 		'month' => 'meses',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\r\\o',
 		'nov' => 'nov',
 		'nov' => 'nov',
 		'november' => 'Nov',
 		'november' => 'Nov',
+		'Oct' => '\\O\\u\\t\\u\\b\\r\\o',
 		'oct' => 'out',
 		'oct' => 'out',
 		'october' => 'Out',
 		'october' => 'Out',
 		'sat' => 'Sab',
 		'sat' => 'Sab',
+		'Sep' => '\\S\\e\\t\\e\\m\\b\\r\\o',
 		'sep' => 'set',
 		'sep' => 'set',
 		'september' => 'Set',
 		'september' => 'Set',
 		'sun' => 'Dom',
 		'sun' => 'Dom',
@@ -123,6 +124,7 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
@@ -159,7 +161,6 @@ return array(
 		'previous' => 'Anterior',
 		'previous' => 'Anterior',
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -167,9 +168,11 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'gnusocial' => 'GNU social',
 		'gnusocial' => 'GNU social',
 		'jdh' => 'Journal du hacker',
 		'jdh' => 'Journal du hacker',
+		'Known' => 'Known based sites',
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Imprimir',
 		'print' => 'Imprimir',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',

+ 3 - 2
app/i18n/pt-br/index.php

@@ -40,7 +40,7 @@ return array(
 		'mark_all_read' => 'Marcar todos como lidos',
 		'mark_all_read' => 'Marcar todos como lidos',
 		'mark_cat_read' => 'Marcar categoria como lida',
 		'mark_cat_read' => 'Marcar categoria como lida',
 		'mark_feed_read' => 'Marcar feed com lido',
 		'mark_feed_read' => 'Marcar feed com lido',
-		'mark_selection_unread' => 'Mark selection as unread',	//TODO
+		'mark_selection_unread' => 'Mark selection as unread',	//TODO - Translation
 		'newer_first' => 'Novos primeiro',
 		'newer_first' => 'Novos primeiro',
 		'non-starred' => 'Mostrar todos, exceto favoritos',
 		'non-starred' => 'Mostrar todos, exceto favoritos',
 		'normal_view' => 'visualização normal',
 		'normal_view' => 'visualização normal',
@@ -53,10 +53,11 @@ return array(
 		'starred' => 'Mostrar apenas os favoritos',
 		'starred' => 'Mostrar apenas os favoritos',
 		'stats' => 'Estatísticas',
 		'stats' => 'Estatísticas',
 		'subscription' => 'Gerenciamento de inscrições',
 		'subscription' => 'Gerenciamento de inscrições',
+		'tags' => 'My labels',	//TODO - Translation
 		'unread' => 'Mostrar apenas os não lidos',
 		'unread' => 'Mostrar apenas os não lidos',
 	),
 	),
 	'share' => 'Compartilhar',
 	'share' => 'Compartilhar',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Tags relacionadas',	//TODO
+		'related' => 'Tags relacionadas',	//TODO - Translation
 	),
 	),
 );
 );

+ 3 - 3
app/i18n/pt-br/install.php

@@ -24,8 +24,8 @@ return array(
 			'ok' => 'Configurações do banco de dados foram salvas.',
 			'ok' => 'Configurações do banco de dados foram salvas.',
 		),
 		),
 		'host' => 'Host',
 		'host' => 'Host',
-		'prefix' => 'Prefixo da tabela',
 		'password' => 'Senha do banco de dados',
 		'password' => 'Senha do banco de dados',
+		'prefix' => 'Prefixo da tabela',
 		'type' => 'Tipo do banco de dados',
 		'type' => 'Tipo do banco de dados',
 		'username' => 'Usuário do banco de dados',
 		'username' => 'Usuário do banco de dados',
 	),
 	),
@@ -69,8 +69,8 @@ return array(
 			'ok' => 'Você tem a extensão JSON.',
 			'ok' => 'Você tem a extensão JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'Não foi possível encontrar o framework Minz.',
 			'nok' => 'Não foi possível encontrar o framework Minz.',

+ 20 - 13
app/i18n/pt-br/sub.php

@@ -2,13 +2,13 @@
 
 
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',// TODO
-		'title' => 'API',// TODO
+		'documentation' => 'Copy the following URL to use it within an external tool.',	//TODO - Translation
+		'title' => 'API',	//TODO - Translation
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
-		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',// TODO
-		'label' => 'Subscribe',// TODO
-		'title' => 'Bookmarklet',// TODO
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',	//TODO - Translation
+		'label' => 'Subscribe',	//TODO - Translation
+		'title' => 'Bookmarklet',	//TODO - Translation
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Categoria',
 		'_' => 'Categoria',
@@ -27,7 +27,7 @@ return array(
 			'password' => 'Senha HTTP',
 			'password' => 'Senha HTTP',
 			'username' => 'Usuário HTTP',
 			'username' => 'Usuário HTTP',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	//TODO
+		'clear_cache' => 'Always clear cache',	//TODO - Translation
 		'css_help' => 'Retorna RSS feeds truncados (atenção, requer mais tempo!)',
 		'css_help' => 'Retorna RSS feeds truncados (atenção, requer mais tempo!)',
 		'css_path' => 'Caminho do CSS do artigo no site original',
 		'css_path' => 'Caminho do CSS do artigo no site original',
 		'description' => 'Descrição',
 		'description' => 'Descrição',
@@ -36,26 +36,33 @@ return array(
 		'informations' => 'Informações',
 		'informations' => 'Informações',
 		'keep_history' => 'Número mínimo de artigos para manter',
 		'keep_history' => 'Número mínimo de artigos para manter',
 		'moved_category_deleted' => 'Quando você deleta uma categoria, seus feeds são automaticamente classificados como <em>%s</em>.',
 		'moved_category_deleted' => 'Quando você deleta uma categoria, seus feeds são automaticamente classificados como <em>%s</em>.',
-		'mute' => 'mute', // TODO
+		'mute' => 'mute',	//TODO - Translation
 		'no_selected' => 'Nenhum feed selecionado.',
 		'no_selected' => 'Nenhum feed selecionado.',
 		'number_entries' => '%d artigos',
 		'number_entries' => '%d artigos',
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility', // TODO
-			'archived' => 'Do not show (archived)', // TODO
+			'_' => 'Visibility',	//TODO - Translation
+			'archived' => 'Do not show (archived)',	//TODO - Translation
 			'main_stream' => 'Mostrar na tela principal',
 			'main_stream' => 'Mostrar na tela principal',
-			'normal' => 'Show in its category', // TODO
+			'normal' => 'Show in its category',	//TODO - Translation
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	//TODO
+		'websub' => 'Notificação instantânea com WebSub',
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
+		'ssl_verify' => 'Verify SSL security',	//TODO - Translation
 		'stats' => 'Estatísticas',
 		'stats' => 'Estatísticas',
 		'think_to_add' => 'Você deve adicionar alguns feeds.',
 		'think_to_add' => 'Você deve adicionar alguns feeds.',
-		'timeout' => 'Timeout in seconds',	//TODO
+		'timeout' => 'Timeout in seconds',	//TODO - Translation
 		'title' => 'Título',
 		'title' => 'Título',
 		'title_add' => 'Adicionar o RSS feed',
 		'title_add' => 'Adicionar o RSS feed',
 		'ttl' => 'Não atualize automáticamente mais que',
 		'ttl' => 'Não atualize automáticamente mais que',
 		'url' => 'Feed URL',
 		'url' => 'Feed URL',
 		'validator' => 'Verifique a validade do feed',
 		'validator' => 'Verifique a validade do feed',
 		'website' => 'URL do site',
 		'website' => 'URL do site',
-		'pubsubhubbub' => 'Notificação instantânea com PubSubHubbub',
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export' => 'Exportar',
 		'export' => 'Exportar',

+ 16 - 12
app/i18n/ru/admin.php

@@ -67,8 +67,8 @@ return array(
 			'ok' => 'У вас установлена библиотека для работы с JSON.',
 			'ok' => 'У вас установлена библиотека для работы с JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'У вас не установлен фрейворк Minz.',
 			'nok' => 'У вас не установлен фрейворк Minz.',
@@ -106,23 +106,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
+		'author' => 'Author',	//TODO - Translation
+		'community' => 'Available community extensions',	//TODO - Translation
+		'description' => 'Description',	//TODO - Translation
 		'disabled' => 'Отключены',
 		'disabled' => 'Отключены',
 		'empty_list' => 'Расширения не установлены',
 		'empty_list' => 'Расширения не установлены',
 		'enabled' => 'Включены',
 		'enabled' => 'Включены',
+		'latest' => 'Installed',	//TODO - Translation
+		'name' => 'Name',	//TODO - Translation
 		'no_configure_view' => 'Это расширение нельзя настроить.',
 		'no_configure_view' => 'Это расширение нельзя настроить.',
 		'system' => array(
 		'system' => array(
 			'_' => 'Системные расширения',
 			'_' => 'Системные расширения',
 			'no_rights' => 'Системные расширения (у вас нет к ним доступа)',
 			'no_rights' => 'Системные расширения (у вас нет к ним доступа)',
 		),
 		),
 		'title' => 'Расширения',
 		'title' => 'Расширения',
+		'update' => 'Update available',	//TODO - Translation
 		'user' => 'Расширения пользователя',
 		'user' => 'Расширения пользователя',
-		'community' => 'Available community extensions', // @todo translate
-		'name' => 'Name', // @todo translate
-		'version' => 'Version', // @todo translate
-		'description' => 'Description', // @todo translate
-		'author' => 'Author', // @todo translate
-		'latest' => 'Installed', // @todo translate
-		'update' => 'Update available', // @todo translate
+		'version' => 'Version',	//TODO - Translation
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Статистика',
 		'_' => 'Статистика',
@@ -162,6 +162,10 @@ return array(
 		'instance-name' => 'Название этого сервера',
 		'instance-name' => 'Название этого сервера',
 		'max-categories' => 'Количество категорий на пользователя',
 		'max-categories' => 'Количество категорий на пользователя',
 		'max-feeds' => 'Количество статей на пользователя',
 		'max-feeds' => 'Количество статей на пользователя',
+		'cookie-duration' => array(
+			'help' => 'in seconds', // @todo translate
+			'number' => 'Duration to keep logged in', // @todo translate
+		),
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 означает неограниченное количество пользователей',
 			'help' => '0 означает неограниченное количество пользователей',
 			'number' => 'Максимальное количество пользователей',
 			'number' => 'Максимальное количество пользователей',
@@ -179,15 +183,15 @@ return array(
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s статей (%s)',
 		'articles_and_size' => '%s статей (%s)',
 		'create' => 'Создать нового пользователя',
 		'create' => 'Создать нового пользователя',
-		'delete_users' => 'Delete user', // TODO
+		'delete_users' => 'Delete user',	//TODO - Translation
 		'language' => 'Язык',
 		'language' => 'Язык',
 		'number' => 'На данный момент создан %d аккаунт',
 		'number' => 'На данный момент создан %d аккаунт',
 		'numbers' => 'На данный момент аккаунтов создано:  %d',
 		'numbers' => 'На данный момент аккаунтов создано:  %d',
 		'password_form' => 'Пароль<br /><small>(для входа через Веб-форму)</small>',
 		'password_form' => 'Пароль<br /><small>(для входа через Веб-форму)</small>',
 		'password_format' => 'Минимум 7 символов',
 		'password_format' => 'Минимум 7 символов',
-		'selected' => 'Selected user', // TODO
+		'selected' => 'Selected user',	//TODO - Translation
 		'title' => 'Управление пользователями',
 		'title' => 'Управление пользователями',
-		'update_users' => 'Update user', // TODO
+		'update_users' => 'Update user',	//TODO - Translation
 		'user_list' => 'Список пользователей',
 		'user_list' => 'Список пользователей',
 		'username' => 'Имя пользователя',
 		'username' => 'Имя пользователя',
 		'users' => 'Пользователи',
 		'users' => 'Пользователи',

+ 134 - 131
app/i18n/ru/conf.php

@@ -6,9 +6,9 @@ return array(
 		'advanced' => 'Продвинутые настройки',
 		'advanced' => 'Продвинутые настройки',
 		'delete_after' => 'Удалять статьи после',
 		'delete_after' => 'Удалять статьи после',
 		'help' => 'Каждую подписку можно настроить более гибко',
 		'help' => 'Каждую подписку можно настроить более гибко',
-		'keep_history_by_feed' => 'Minimum number of articles to keep by feed',
+		'keep_history_by_feed' => 'Minimum number of articles to keep by feed', 	//TODO - Translation
 		'optimize' => 'Оптимизировать базу данных',
 		'optimize' => 'Оптимизировать базу данных',
-		'optimize_help' => 'To do occasionally to reduce the size of the database',
+		'optimize_help' => 'To do occasionally to reduce the size of the database', 	//TODO - Translation
 		'purge_now' => 'Очистить сейчас',
 		'purge_now' => 'Очистить сейчас',
 		'title' => 'Архивация',
 		'title' => 'Архивация',
 		'ttl' => 'Не обновлять чаще чем',
 		'ttl' => 'Не обновлять чаще чем',
@@ -16,169 +16,172 @@ return array(
 	'display' => array(
 	'display' => array(
 		'_' => 'Display',
 		'_' => 'Display',
 		'icon' => array(
 		'icon' => array(
-			'bottom_line' => 'Bottom line',
-			'entry' => 'Article icons',
-			'publication_date' => 'Date of publication',
-			'related_tags' => 'Related tags',	//TODO
-			'sharing' => 'Sharing',
-			'top_line' => 'Top line',
+			'bottom_line' => 'Bottom line',	//TODO - Translation
+			'entry' => 'Article icons',	//TODO - Translation
+			'publication_date' => 'Date of publication',	//TODO - Translation
+			'related_tags' => 'Related tags',	//TODO - Translation
+			'sharing' => 'Sharing',	//TODO - Translation
+			'top_line' => 'Top line',	//TODO - Translation
 		),
 		),
 		'language' => 'Язык',
 		'language' => 'Язык',
 		'notif_html5' => array(
 		'notif_html5' => array(
-			'seconds' => 'seconds (0 means no timeout)',
-			'timeout' => 'HTML5 notification timeout',
+			'seconds' => 'seconds (0 means no timeout)',	//TODO - Translation
+			'timeout' => 'HTML5 notification timeout',	//TODO - Translation
 		),
 		),
+		'show_nav_buttons' => 'Show the navigation buttons',	//TODO - Translation
 		'theme' => 'Тема',
 		'theme' => 'Тема',
-		'title' => 'Display',
+		'title' => 'Display',	//TODO - Translation
 		'width' => array(
 		'width' => array(
-			'content' => 'Content width',
-			'large' => 'Large',
-			'medium' => 'Medium',
-			'no_limit' => 'No limit',
-			'thin' => 'Thin',
+			'content' => 'Content width',	//TODO - Translation
+			'large' => 'Large',	//TODO - Translation
+			'medium' => 'Medium',	//TODO - Translation
+			'no_limit' => 'No limit',	//TODO - Translation
+			'thin' => 'Thin',	//TODO - Translation
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	//TODO
-	),
-	'query' => array(
-		'_' => 'User queries',
-		'deprecated' => 'This query is no longer valid. The referenced category or feed has been deleted.',
-		'display' => 'Display user query results', // TODO
-		'filter' => 'Filter applied:',
-		'get_all' => 'Display all articles',
-		'get_category' => 'Display "%s" category',
-		'get_favorite' => 'Display favorite articles',
-		'get_feed' => 'Display "%s" feed',
-		'no_filter' => 'No filter',
-		'none' => 'You haven’t created any user query yet.',
-		'number' => 'Query n°%d',
-		'order_asc' => 'Display oldest articles first',
-		'order_desc' => 'Display newest articles first',
-		'remove' => 'Remove user query', // TODO
-		'search' => 'Search for "%s"',
-		'state_0' => 'Display all articles',
-		'state_1' => 'Display read articles',
-		'state_2' => 'Display unread articles',
-		'state_3' => 'Display all articles',
-		'state_4' => 'Display favorite articles',
-		'state_5' => 'Display read favorite articles',
-		'state_6' => 'Display unread favorite articles',
-		'state_7' => 'Display favorite articles',
-		'state_8' => 'Display not favorite articles',
-		'state_9' => 'Display read not favorite articles',
-		'state_10' => 'Display unread not favorite articles',
-		'state_11' => 'Display not favorite articles',
-		'state_12' => 'Display all articles',
-		'state_13' => 'Display read articles',
-		'state_14' => 'Display unread articles',
-		'state_15' => 'Display all articles',
-		'title' => 'User queries',
 	),
 	),
 	'profile' => array(
 	'profile' => array(
-		'_' => 'Profile management',
+		'_' => 'Profile management',	//TODO - Translation
 		'delete' => array(
 		'delete' => array(
-			'_' => 'Account deletion',
-			'warn' => 'Your account and all the related data will be deleted.',
+			'_' => 'Account deletion',	//TODO - Translation
+			'warn' => 'Your account and all the related data will be deleted.',	//TODO - Translation
 		),
 		),
-		'password_api' => 'Password API<br /><small>(e.g., for mobile apps)</small>',
-		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
-		'password_format' => 'At least 7 characters',
-		'title' => 'Profile',
+		'password_api' => 'Password API<br /><small>(e.g., for mobile apps)</small>',	//TODO - Translation
+		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',	//TODO - Translation
+		'password_format' => 'At least 7 characters',	//TODO - Translation
+		'title' => 'Profile',	//TODO - Translation
+	),
+	'query' => array(
+		'_' => 'User queries',
+		'deprecated' => 'This query is no longer valid. The referenced category or feed has been deleted.',	//TODO - Translation
+		'display' => 'Display user query results',	//TODO - Translation
+		'filter' => 'Filter applied:',	//TODO - Translation
+		'get_all' => 'Display all articles',	//TODO - Translation
+		'get_category' => 'Display "%s" category',	//TODO - Translation
+		'get_favorite' => 'Display favorite articles',	//TODO - Translation
+		'get_feed' => 'Display "%s" feed',	//TODO - Translation
+		'no_filter' => 'No filter',	//TODO - Translation
+		'none' => 'You haven’t created any user query yet.',	//TODO - Translation
+		'number' => 'Query n°%d',	//TODO - Translation
+		'order_asc' => 'Display oldest articles first',	//TODO - Translation
+		'order_desc' => 'Display newest articles first',	//TODO - Translation
+		'remove' => 'Remove user query',	//TODO - Translation
+		'search' => 'Search for "%s"',	//TODO - Translation
+		'state_0' => 'Display all articles',	//TODO - Translation
+		'state_1' => 'Display read articles',	//TODO - Translation
+		'state_2' => 'Display unread articles',	//TODO - Translation
+		'state_3' => 'Display all articles',	//TODO - Translation
+		'state_4' => 'Display favorite articles',	//TODO - Translation
+		'state_5' => 'Display read favorite articles',	//TODO - Translation
+		'state_6' => 'Display unread favorite articles',	//TODO - Translation
+		'state_7' => 'Display favorite articles',	//TODO - Translation
+		'state_8' => 'Display not favorite articles',	//TODO - Translation
+		'state_9' => 'Display read not favorite articles',	//TODO - Translation
+		'state_10' => 'Display unread not favorite articles',	//TODO - Translation
+		'state_11' => 'Display not favorite articles',	//TODO - Translation
+		'state_12' => 'Display all articles',	//TODO - Translation
+		'state_13' => 'Display read articles',	//TODO - Translation
+		'state_14' => 'Display unread articles',	//TODO - Translation
+		'state_15' => 'Display all articles',	//TODO - Translation
+		'title' => 'User queries',	//TODO - Translation
 	),
 	),
 	'reading' => array(
 	'reading' => array(
-		'_' => 'Reading',
-		'after_onread' => 'After “mark all as read”,',
-		'articles_per_page' => 'Number of articles per page',
-		'auto_load_more' => 'Load next articles at the page bottom',
-		'auto_remove_article' => 'Hide articles after reading',
-		'mark_updated_article_unread' => 'Mark updated articles as unread',
-		'confirm_enabled' => 'Display a confirmation dialog on “mark all as read” actions',
-		'display_articles_unfolded' => 'Show articles unfolded by default',
-		'display_categories_unfolded' => 'Show categories folded by default',
-		'hide_read_feeds' => 'Hide categories & feeds with no unread article (does not work with “Show all articles” configuration)',
-		'img_with_lazyload' => 'Use "lazy load" mode to load pictures',
-		'sides_close_article' => 'Clicking outside of article text area closes the article',	//TODO
-		'jump_next' => 'jump to next unread sibling (feed or category)',
-		'number_divided_when_reader' => 'Divided by 2 in the reading view.',
+		'_' => 'Reading',	//TODO - Translation
+		'after_onread' => 'After “mark all as read”,',	//TODO - Translation
+		'articles_per_page' => 'Number of articles per page',	//TODO - Translation
+		'auto_load_more' => 'Load next articles at the page bottom',	//TODO - Translation
+		'auto_remove_article' => 'Hide articles after reading',	//TODO - Translation
+		'confirm_enabled' => 'Display a confirmation dialog on “mark all as read” actions',	//TODO - Translation
+		'display_articles_unfolded' => 'Show articles unfolded by default',	//TODO - Translation
+		'display_categories_unfolded' => 'Show categories folded by default',	//TODO - Translation
+		'hide_read_feeds' => 'Hide categories & feeds with no unread article (does not work with “Show all articles” configuration)',	//TODO - Translation
+		'img_with_lazyload' => 'Use "lazy load" mode to load pictures',	//TODO - Translation
+		'jump_next' => 'jump to next unread sibling (feed or category)',	//TODO - Translation
+		'mark_updated_article_unread' => 'Mark updated articles as unread',	//TODO - Translation
+		'number_divided_when_reader' => 'Divided by 2 in the reading view.',	//TODO - Translation
 		'read' => array(
 		'read' => array(
-			'article_open_on_website' => 'when article is opened on its original website',
-			'article_viewed' => 'when article is viewed',
-			'scroll' => 'while scrolling',
-			'upon_reception' => 'upon reception of the article',
-			'when' => 'Mark article as read…',
+			'article_open_on_website' => 'when article is opened on its original website',	//TODO - Translation
+			'article_viewed' => 'when article is viewed',	//TODO - Translation
+			'scroll' => 'while scrolling',	//TODO - Translation
+			'upon_reception' => 'upon reception of the article',	//TODO - Translation
+			'when' => 'Mark article as read…',	//TODO - Translation
 		),
 		),
 		'show' => array(
 		'show' => array(
-			'_' => 'Articles to display',
-			'adaptive' => 'Adjust showing',
-			'all_articles' => 'Show all articles',
-			'unread' => 'Show only unread',
+			'_' => 'Articles to display',	//TODO - Translation
+			'adaptive' => 'Adjust showing',	//TODO - Translation
+			'all_articles' => 'Show all articles',	//TODO - Translation
+			'unread' => 'Show only unread',	//TODO - Translation
 		),
 		),
+		'sides_close_article' => 'Clicking outside of article text area closes the article',	//TODO - Translation
 		'sort' => array(
 		'sort' => array(
-			'_' => 'Sort order',
-			'newer_first' => 'Newer first',
-			'older_first' => 'Oldest first',
+			'_' => 'Sort order',	//TODO - Translation
+			'newer_first' => 'Newer first',	//TODO - Translation
+			'older_first' => 'Oldest first',	//TODO - Translation
 		),
 		),
-		'sticky_post' => 'Stick the article to the top when opened',
-		'title' => 'Reading',
+		'sticky_post' => 'Stick the article to the top when opened',	//TODO - Translation
+		'title' => 'Reading',	//TODO - Translation
 		'view' => array(
 		'view' => array(
-			'default' => 'Default view',
-			'global' => 'Global view',
-			'normal' => 'Normal view',
-			'reader' => 'Reading view',
+			'default' => 'Default view',	//TODO - Translation
+			'global' => 'Global view',	//TODO - Translation
+			'normal' => 'Normal view',	//TODO - Translation
+			'reader' => 'Reading view',	//TODO - Translation
 		),
 		),
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
-		'_' => 'Sharing',
-		'add' => 'Add a sharing method', // TODO
+		'_' => 'Sharing',	//TODO - Translation
+		'add' => 'Add a sharing method',	//TODO - Translation
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
+		'email' => 'Email',	//TODO - Translation
 		'facebook' => 'Facebook',
 		'facebook' => 'Facebook',
 		'g+' => 'Google+',
 		'g+' => 'Google+',
-		'more_information' => 'More information',
-		'print' => 'Print',
-		'remove' => 'Remove sharing method', // TODO
+		'more_information' => 'More information',	//TODO - Translation
+		'print' => 'Print',	//TODO - Translation
+		'remove' => 'Remove sharing method',	//TODO - Translation
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
-		'share_name' => 'Share name to display',
-		'share_url' => 'Share URL to use',
+		'share_name' => 'Share name to display',	//TODO - Translation
+		'share_url' => 'Share URL to use',	//TODO - Translation
 		'title' => 'Sharing',
 		'title' => 'Sharing',
 		'twitter' => 'Twitter',
 		'twitter' => 'Twitter',
 		'wallabag' => 'wallabag',
 		'wallabag' => 'wallabag',
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
-		'_' => 'Shortcuts',
-		'article_action' => 'Article actions',
-		'auto_share' => 'Share',
-		'auto_share_help' => 'If there is only one sharing mode, it is used. Else modes are accessible by their number.',
-		'close_dropdown' => 'Close menus',
-		'collapse_article' => 'Collapse',
-		'first_article' => 'Skip to the first article',
-		'focus_search' => 'Access search box',
-		'global_view' => 'Switch to global view',  // TODO
-		'help' => 'Display documentation',
-		'javascript' => 'JavaScript must be enabled in order to use shortcuts',
-		'last_article' => 'Skip to the last article',
-		'load_more' => 'Load more articles',
-		'mark_read' => 'Mark as read',
-		'mark_favorite' => 'Mark as favourite',
-		'navigation' => 'Navigation',
-		'navigation_help' => 'With the "Shift" modifier, navigation shortcuts apply on feeds.<br/>With the "Alt" modifier, navigation shortcuts apply on categories.',
-		'next_article' => 'Skip to the next article',
-		'normal_view' => 'Switch to normal view', // TODO
-		'other_action' => 'Other actions',
-		'previous_article' => 'Skip to the previous article',
-		'reading_view' => 'Switch to reading view', // TODO
-		'rss_view' => 'Open RSS view in a new tab', // TODO
-		'see_on_website' => 'See on original website',
-		'shift_for_all_read' => '+ <code>shift</code> to mark all articles as read',
-		'title' => 'Shortcuts',
-		'user_filter' => 'Access user filters',
-		'user_filter_help' => 'If there is only one user filter, it is used. Else filters are accessible by their number.',
-		'views' => 'Views', // TODO
+		'_' => 'Shortcuts',	//TODO - Translation
+		'article_action' => 'Article actions',	//TODO - Translation
+		'auto_share' => 'Share',	//TODO - Translation
+		'auto_share_help' => 'If there is only one sharing mode, it is used. Else modes are accessible by their number.',	//TODO - Translation
+		'close_dropdown' => 'Close menus',	//TODO - Translation
+		'collapse_article' => 'Collapse',	//TODO - Translation
+		'first_article' => 'Skip to the first article',	//TODO - Translation
+		'focus_search' => 'Access search box',	//TODO - Translation
+		'global_view' => 'Switch to global view',	//TODO - Translation
+		'help' => 'Display documentation',	//TODO - Translation
+		'javascript' => 'JavaScript must be enabled in order to use shortcuts',	//TODO - Translation
+		'last_article' => 'Skip to the last article',	//TODO - Translation
+		'load_more' => 'Load more articles',	//TODO - Translation
+		'mark_read' => 'Mark as read',	//TODO - Translation
+		'mark_favorite' => 'Mark as favourite',	//TODO - Translation
+		'navigation' => 'Navigation',	//TODO - Translation
+		'navigation_help' => 'With the "Shift" modifier, navigation shortcuts apply on feeds.<br/>With the "Alt" modifier, navigation shortcuts apply on categories.',	//TODO - Translation
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	//TODO - Translation
+		'next_article' => 'Skip to the next article',	//TODO - Translation
+		'normal_view' => 'Switch to normal view',	//TODO - Translation
+		'other_action' => 'Other actions',	//TODO - Translation
+		'previous_article' => 'Skip to the previous article',	//TODO - Translation
+		'reading_view' => 'Switch to reading view',	//TODO - Translation
+		'rss_view' => 'Open RSS view in a new tab',	//TODO - Translation
+		'see_on_website' => 'See on original website',	//TODO - Translation
+		'shift_for_all_read' => '+ <code>shift</code> to mark all articles as read',	//TODO - Translation
+		'skip_next_article' => 'Focus next without opening',	//TODO - Translation
+		'skip_previous_article' => 'Focus previous without opening',	//TODO - Translation
+		'title' => 'Shortcuts',	//TODO - Translation
+		'user_filter' => 'Access user filters',	//TODO - Translation
+		'user_filter_help' => 'If there is only one user filter, it is used. Else filters are accessible by their number.',	//TODO - Translation
+		'views' => 'Views',	//TODO - Translation
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'articles_and_size' => '%s articles (%s)',
-		'current' => 'Current user',
-		'is_admin' => 'is administrator',
-		'users' => 'Users',
+		'articles_and_size' => '%s articles (%s)',	//TODO - Translation
+		'current' => 'Current user',	//TODO - Translation
+		'is_admin' => 'is administrator',	//TODO - Translation
+		'users' => 'Users',	//TODO - Translation
 	),
 	),
 );
 );

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

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

+ 135 - 133
app/i18n/ru/gen.php

@@ -2,117 +2,117 @@
 
 
 return array(
 return array(
 	'action' => array(
 	'action' => array(
-		'actualize' => 'Actualize',
-		'back_to_rss_feeds' => '← Go back to your RSS feeds',
-		'cancel' => 'Cancel',
-		'create' => 'Create',
-		'disable' => 'Disable',
-		'empty' => 'Empty',
-		'enable' => 'Enable',
-		'export' => 'Export',
-		'filter' => 'Filter',
-		'import' => 'Import',
-		'manage' => 'Manage',
-		'mark_favorite' => 'Mark as favourite',
-		'mark_read' => 'Mark as read',
-		'remove' => 'Remove',
-		'see_website' => 'See website',
-		'submit' => 'Submit',
-		'truncate' => 'Delete all articles',
-		'update' => 'Update', // TODO
+		'actualize' => 'Actualize',	//TODO - Translation
+		'back_to_rss_feeds' => '← Go back to your RSS feeds',	//TODO - Translation
+		'cancel' => 'Cancel',	//TODO - Translation
+		'create' => 'Create',	//TODO - Translation
+		'disable' => 'Disable',	//TODO - Translation
+		'empty' => 'Empty',	//TODO - Translation
+		'enable' => 'Enable',	//TODO - Translation
+		'export' => 'Export',	//TODO - Translation
+		'filter' => 'Filter',	//TODO - Translation
+		'import' => 'Import',	//TODO - Translation
+		'manage' => 'Manage',	//TODO - Translation
+		'mark_favorite' => 'Mark as favourite',	//TODO - Translation
+		'mark_read' => 'Mark as read',	//TODO - Translation
+		'remove' => 'Remove',	//TODO - Translation
+		'see_website' => 'See website',	//TODO - Translation
+		'submit' => 'Submit',	//TODO - Translation
+		'truncate' => 'Delete all articles',	//TODO - Translation
+		'update' => 'Update',	//TODO - Translation
 	),
 	),
 	'auth' => array(
 	'auth' => array(
-		'email' => 'Email address',
-		'keep_logged_in' => 'Keep me logged in <small>(%s дней)</small>',
-		'login' => 'Login',
-		'logout' => 'Logout',
+		'email' => 'Email address',	//TODO - Translation
+		'keep_logged_in' => 'Keep me logged in <small>(%s дней)</small>',	//TODO - Translation
+		'login' => 'Login',	//TODO - Translation
+		'logout' => 'Logout',	//TODO - Translation
 		'password' => array(
 		'password' => array(
-			'_' => 'Password',
-			'format' => '<small>At least 7 characters</small>',
+			'_' => 'Password',	//TODO - Translation
+			'format' => '<small>At least 7 characters</small>',	//TODO - Translation
 		),
 		),
 		'registration' => array(
 		'registration' => array(
-			'_' => 'New account',
-			'ask' => 'Create an account?',
-			'title' => 'Account creation',
+			'_' => 'New account',	//TODO - Translation
+			'ask' => 'Create an account?',	//TODO - Translation
+			'title' => 'Account creation',	//TODO - Translation
 		),
 		),
-		'reset' => 'Authentication reset',
+		'reset' => 'Authentication reset',	//TODO - Translation
 		'username' => array(
 		'username' => array(
-			'_' => 'Username',
-			'admin' => 'Administrator username',
-			'format' => '<small>maximum 16 alphanumeric characters</small>',
+			'_' => 'Username',	//TODO - Translation
+			'admin' => 'Administrator username',	//TODO - Translation
+			'format' => '<small>maximum 16 alphanumeric characters</small>',	//TODO - Translation
 		),
 		),
 	),
 	),
 	'date' => array(
 	'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' => 'apr',
-		'april' => 'Apr',
-		'aug' => 'aug',
-		'august' => 'Aug',
-		'before_yesterday' => 'Before yesterday',
-		'dec' => 'dec',
-		'december' => 'Dec',
-		'feb' => 'feb',
-		'february' => 'Feb',
-		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
-		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',
-		'fri' => 'Fri',
-		'jan' => 'jan',
-		'january' => 'Jan',
-		'jul' => 'jul',
-		'july' => 'Jul',
-		'jun' => 'jun',
-		'june' => 'Jun',
-		'last_3_month' => 'Last three months',
-		'last_6_month' => 'Last six months',
-		'last_month' => 'Last month',
-		'last_week' => 'Last week',
-		'last_year' => 'Last year',
-		'mar' => 'mar',
-		'march' => 'Mar',
-		'may' => 'May',
-		'may_' => 'May',
-		'mon' => 'Mon',
-		'month' => 'months',
-		'nov' => 'nov',
-		'november' => 'Nov',
-		'oct' => 'oct',
-		'october' => 'Oct',
-		'sat' => 'Sat',
-		'sep' => 'sep',
-		'september' => 'Sep',
-		'sun' => 'Sun',
-		'thu' => 'Thu',
-		'today' => 'Today',
-		'tue' => 'Tue',
-		'wed' => 'Wed',
-		'yesterday' => 'Yesterday',
+		'Apr' => '\\A\\p\\r\\i\\l',	//TODO - Translation
+		'apr' => 'apr',	//TODO - Translation
+		'april' => 'Apr',	//TODO - Translation
+		'Aug' => '\\A\\u\\g\\u\\s\\t',	//TODO - Translation
+		'aug' => 'aug',	//TODO - Translation
+		'august' => 'Aug',	//TODO - Translation
+		'before_yesterday' => 'Before yesterday',	//TODO - Translation
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',	//TODO - Translation
+		'dec' => 'dec',	//TODO - Translation
+		'december' => 'Dec',	//TODO - Translation
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',	//TODO - Translation
+		'feb' => 'feb',	//TODO - Translation
+		'february' => 'Feb',	//TODO - Translation
+		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',	//TODO - Translation
+		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',	//TODO - Translation
+		'fri' => 'Fri',	//TODO - Translation
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',	//TODO - Translation
+		'jan' => 'jan',	//TODO - Translation
+		'january' => 'Jan',	//TODO - Translation
+		'Jul' => '\\J\\u\\l\\y',	//TODO - Translation
+		'jul' => 'jul',	//TODO - Translation
+		'july' => 'Jul',	//TODO - Translation
+		'Jun' => '\\J\\u\\n\\e',	//TODO - Translation
+		'jun' => 'jun',	//TODO - Translation
+		'june' => 'Jun',	//TODO - Translation
+		'last_3_month' => 'Last three months',	//TODO - Translation
+		'last_6_month' => 'Last six months',	//TODO - Translation
+		'last_month' => 'Last month',	//TODO - Translation
+		'last_week' => 'Last week',	//TODO - Translation
+		'last_year' => 'Last year',	//TODO - Translation
+		'Mar' => '\\M\\a\\r\\c\\h',	//TODO - Translation
+		'mar' => 'mar',	//TODO - Translation
+		'march' => 'Mar',	//TODO - Translation
+		'May' => '\\M\\a\\y',	//TODO - Translation
+		'may' => 'May',	//TODO - Translation
+		'may_' => 'May',	//TODO - Translation
+		'mon' => 'Mon',	//TODO - Translation
+		'month' => 'months',	//TODO - Translation
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',	//TODO - Translation
+		'nov' => 'nov',	//TODO - Translation
+		'november' => 'Nov',	//TODO - Translation
+		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',	//TODO - Translation
+		'oct' => 'oct',	//TODO - Translation
+		'october' => 'Oct',	//TODO - Translation
+		'sat' => 'Sat',	//TODO - Translation
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',	//TODO - Translation
+		'sep' => 'sep',	//TODO - Translation
+		'september' => 'Sep',	//TODO - Translation
+		'sun' => 'Sun',	//TODO - Translation
+		'thu' => 'Thu',	//TODO - Translation
+		'today' => 'Today',	//TODO - Translation
+		'tue' => 'Tue',	//TODO - Translation
+		'wed' => 'Wed',	//TODO - Translation
+		'yesterday' => 'Yesterday',	//TODO - Translation
 	),
 	),
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
-		'about' => 'About FreshRSS',
+		'_' => 'FreshRSS',	//TODO - Translation
+		'about' => 'About FreshRSS',	//TODO - Translation
 	),
 	),
 	'js' => array(
 	'js' => array(
-		'category_empty' => 'Empty category',
-		'confirm_action' => 'Are you sure you want to perform this action? It cannot be cancelled!',
-		'confirm_action_feed_cat' => 'Are you sure you want to perform this action? You will lose related favorites and user queries. It cannot be cancelled!',
+		'category_empty' => 'Empty category',	//TODO - Translation
+		'confirm_action' => 'Are you sure you want to perform this action? It cannot be cancelled!',	//TODO - Translation
+		'confirm_action_feed_cat' => 'Are you sure you want to perform this action? You will lose related favorites and user queries. It cannot be cancelled!',	//TODO - Translation
 		'feedback' => array(
 		'feedback' => array(
-			'body_new_articles' => 'There are %%d new articles to read on FreshRSS.',
-			'request_failed' => 'A request has failed, it may have been caused by Internet connection problems.',
-			'title_new_articles' => 'FreshRSS: new articles!',
+			'body_new_articles' => 'There are %%d new articles to read on FreshRSS.',	//TODO - Translation
+			'request_failed' => 'A request has failed, it may have been caused by Internet connection problems.',	//TODO - Translation
+			'title_new_articles' => 'FreshRSS: new articles!',	//TODO - Translation
 		),
 		),
-		'new_article' => 'There are new available articles, click to refresh the page.',
-		'should_be_activated' => 'JavaScript must be enabled',
+		'new_article' => 'There are new available articles, click to refresh the page.',	//TODO - Translation
+		'should_be_activated' => 'JavaScript must be enabled',	//TODO - Translation
 	),
 	),
 	'lang' => array(
 	'lang' => array(
 		'cz' => 'Čeština',
 		'cz' => 'Čeština',
@@ -124,43 +124,43 @@ return array(
 		'it' => 'Italiano',
 		'it' => 'Italiano',
 		'kr' => '한국어',
 		'kr' => '한국어',
 		'nl' => 'Nederlands',
 		'nl' => 'Nederlands',
+		'oc' => 'Occitan',
 		'pt-br' => 'Português (Brasil)',
 		'pt-br' => 'Português (Brasil)',
 		'ru' => 'Русский',
 		'ru' => 'Русский',
 		'tr' => 'Türkçe',
 		'tr' => 'Türkçe',
 		'zh-cn' => '简体中文',
 		'zh-cn' => '简体中文',
 	),
 	),
 	'menu' => array(
 	'menu' => array(
-		'about' => 'About',
-		'admin' => 'Administration',
-		'archiving' => 'Archiving',
-		'authentication' => 'Authentication',
-		'check_install' => 'Installation checking',
-		'configuration' => 'Configuration',
-		'display' => 'Display',
-		'extensions' => 'Extensions',
-		'logs' => 'Logs',
-		'queries' => 'User queries',
-		'reading' => 'Reading',
-		'search' => 'Search words or #tags',
-		'sharing' => 'Sharing',
-		'shortcuts' => 'Shortcuts',
-		'stats' => 'Statistics',
-		'system' => 'System configuration',
-		'update' => 'Update',
-		'user_management' => 'Manage users',
-		'user_profile' => 'Profile',
+		'about' => 'About',	//TODO - Translation
+		'admin' => 'Administration',	//TODO - Translation
+		'archiving' => 'Archiving',	//TODO - Translation
+		'authentication' => 'Authentication',	//TODO - Translation
+		'check_install' => 'Installation checking',	//TODO - Translation
+		'configuration' => 'Configuration',	//TODO - Translation
+		'display' => 'Display',	//TODO - Translation
+		'extensions' => 'Extensions',	//TODO - Translation
+		'logs' => 'Logs',	//TODO - Translation
+		'queries' => 'User queries',	//TODO - Translation
+		'reading' => 'Reading',	//TODO - Translation
+		'search' => 'Search words or #tags',	//TODO - Translation
+		'sharing' => 'Sharing',	//TODO - Translation
+		'shortcuts' => 'Shortcuts',	//TODO - Translation
+		'stats' => 'Statistics',	//TODO - Translation
+		'system' => 'System configuration',	//TODO - Translation
+		'update' => 'Update',	//TODO - Translation
+		'user_management' => 'Manage users',	//TODO - Translation
+		'user_profile' => 'Profile',	//TODO - Translation
 	),
 	),
 	'pagination' => array(
 	'pagination' => array(
-		'first' => 'First',
-		'last' => 'Last',
-		'load_more' => 'Load more articles',
-		'mark_all_read' => 'Mark all as read',
-		'next' => 'Next',
-		'nothing_to_load' => 'There are no more articles',
-		'previous' => 'Previous',
+		'first' => 'First',	//TODO - Translation
+		'last' => 'Last',	//TODO - Translation
+		'load_more' => 'Load more articles',	//TODO - Translation
+		'mark_all_read' => 'Mark all as read',	//TODO - Translation
+		'next' => 'Next',	//TODO - Translation
+		'nothing_to_load' => 'There are no more articles',	//TODO - Translation
+		'previous' => 'Previous',	//TODO - Translation
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',
 		'blogotext' => 'Blogotext',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
 		'diaspora' => 'Diaspora*',
 		'email' => 'Email',
 		'email' => 'Email',
@@ -168,9 +168,11 @@ return array(
 		'g+' => 'Google+',
 		'g+' => 'Google+',
 		'gnusocial' => 'GNU social',
 		'gnusocial' => 'GNU social',
 		'jdh' => 'Journal du hacker',
 		'jdh' => 'Journal du hacker',
+		'Known' => 'Known based sites',
 		'linkedin' => 'LinkedIn',
 		'linkedin' => 'LinkedIn',
 		'mastodon' => 'Mastodon',
 		'mastodon' => 'Mastodon',
 		'movim' => 'Movim',
 		'movim' => 'Movim',
+		'pinboard' => 'Pinboard',
 		'pocket' => 'Pocket',
 		'pocket' => 'Pocket',
 		'print' => 'Print',
 		'print' => 'Print',
 		'shaarli' => 'Shaarli',
 		'shaarli' => 'Shaarli',
@@ -179,16 +181,16 @@ return array(
 		'wallabagv2' => 'wallabag v2',
 		'wallabagv2' => 'wallabag v2',
 	),
 	),
 	'short' => array(
 	'short' => array(
-		'attention' => 'Warning!',
-		'blank_to_disable' => 'Leave blank to disable',
-		'by_author' => 'By:',
-		'by_default' => 'By default',
-		'damn' => 'Damn!',
-		'default_category' => 'Uncategorized',
-		'no' => 'No',
-		'not_applicable' => 'Not available',
-		'ok' => 'Ok!',
-		'or' => 'or',
-		'yes' => 'Yes',
+		'attention' => 'Warning!',	//TODO - Translation
+		'blank_to_disable' => 'Leave blank to disable',	//TODO - Translation
+		'by_author' => 'By:',	//TODO - Translation
+		'by_default' => 'By default',	//TODO - Translation
+		'damn' => 'Damn!',	//TODO - Translation
+		'default_category' => 'Uncategorized',	//TODO - Translation
+		'no' => 'No',	//TODO - Translation
+		'not_applicable' => 'Not available',	//TODO - Translation
+		'ok' => 'Ok!',	//TODO - Translation
+		'or' => 'or',	//TODO - Translation
+		'yes' => 'Yes',	//TODO - Translation
 	),
 	),
 );
 );

+ 36 - 35
app/i18n/ru/index.php

@@ -2,32 +2,32 @@
 
 
 return array(
 return array(
 	'about' => array(
 	'about' => array(
-		'_' => 'About',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
-		'bugs_reports' => 'Bugs reports',
-		'credits' => 'Credits',
-		'credits_content' => 'Some design elements come from <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> although FreshRSS doesn’t use this framework. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Icons</a> come from <a href="https://www.gnome.org/">GNOME project</a>. <em>Open Sans</em> font police has been created by <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS is based on <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, a PHP framework.',
-		'freshrss_description' => 'FreshRSS is a RSS feeds aggregator to self-host like <a href="http://tontof.net/kriss/feed/">Kriss Feed</a> or <a href="http://leed.idleman.fr/">Leed</a>. It is light and easy to take in hand while being powerful and configurable tool.',
-		'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">on Github</a>',
-		'license' => 'License',
-		'project_website' => 'Project website',
-		'title' => 'About',
-		'version' => 'Version',
-		'website' => 'Website',
+		'_' => 'About',	//TODO - Translation
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	//TODO - Translation
+		'bugs_reports' => 'Bugs reports',	//TODO - Translation
+		'credits' => 'Credits',	//TODO - Translation
+		'credits_content' => 'Some design elements come from <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> although FreshRSS doesn’t use this framework. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Icons</a> come from <a href="https://www.gnome.org/">GNOME project</a>. <em>Open Sans</em> font police has been created by <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS is based on <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, a PHP framework.',	//TODO - Translation
+		'freshrss_description' => 'FreshRSS is a RSS feeds aggregator to self-host like <a href="http://tontof.net/kriss/feed/">Kriss Feed</a> or <a href="http://leed.idleman.fr/">Leed</a>. It is light and easy to take in hand while being powerful and configurable tool.',	//TODO - Translation
+		'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">on Github</a>',	//TODO - Translation
+		'license' => 'License',	//TODO - Translation
+		'project_website' => 'Project website',	//TODO - Translation
+		'title' => 'About',	//TODO - Translation
+		'version' => 'Version',	//TODO - Translation
+		'website' => 'Website',	//TODO - Translation
 	),
 	),
 	'feed' => array(
 	'feed' => array(
-		'add' => 'You may add some feeds.',
-		'empty' => 'There is no article to show.',
-		'rss_of' => 'RSS feed of %s',
-		'title' => 'Your RSS feeds',
-		'title_global' => 'Global view',
-		'title_fav' => 'Your favourites',
+		'add' => 'You may add some feeds.',	//TODO - Translation
+		'empty' => 'There is no article to show.',	//TODO - Translation
+		'rss_of' => 'RSS feed of %s',	//TODO - Translation
+		'title' => 'Your RSS feeds',	//TODO - Translation
+		'title_global' => 'Global view',	//TODO - Translation
+		'title_fav' => 'Your favourites',	//TODO - Translation
 	),
 	),
 	'log' => array(
 	'log' => array(
 		'_' => 'Logs',
 		'_' => 'Logs',
-		'clear' => 'Clear the logs',
-		'empty' => 'Log file is empty',
-		'title' => 'Logs',
+		'clear' => 'Clear the logs',	//TODO - Translation
+		'empty' => 'Log file is empty',	//TODO - Translation
+		'title' => 'Logs',	//TODO - Translation
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'About FreshRSS',
 		'about' => 'About FreshRSS',
@@ -40,23 +40,24 @@ return array(
 		'mark_all_read' => 'Mark all as read',
 		'mark_all_read' => 'Mark all as read',
 		'mark_cat_read' => 'Mark category as read',
 		'mark_cat_read' => 'Mark category as read',
 		'mark_feed_read' => 'Mark feed as read',
 		'mark_feed_read' => 'Mark feed as read',
-		'mark_selection_unread' => 'Mark selection as unread',	//TODO
-		'newer_first' => 'Newer first',
-		'non-starred' => 'Show all but favorites',
-		'normal_view' => 'Normal view',
-		'older_first' => 'Oldest first',
-		'queries' => 'User queries',
-		'read' => 'Show only read',
-		'reader_view' => 'Reading view',
-		'rss_view' => 'RSS feed',
-		'search_short' => 'Search',
-		'starred' => 'Show only favorites',
-		'stats' => 'Statistics',
+		'mark_selection_unread' => 'Mark selection as unread',	//TODO - Translation
+		'newer_first' => 'Newer first',	//TODO - Translation
+		'non-starred' => 'Show all but favorites',	//TODO - Translation
+		'normal_view' => 'Normal view',	//TODO - Translation
+		'older_first' => 'Oldest first',	//TODO - Translation
+		'queries' => 'User queries',	//TODO - Translation
+		'read' => 'Show only read',	//TODO - Translation
+		'reader_view' => 'Reading view',	//TODO - Translation
+		'rss_view' => 'RSS feed',	//TODO - Translation
+		'search_short' => 'Search',	//TODO - Translation
+		'starred' => 'Show only favorites',	//TODO - Translation
+		'stats' => 'Statistics',	//TODO - Translation
 		'subscription' => 'Subscriptions management',
 		'subscription' => 'Subscriptions management',
-		'unread' => 'Show only unread',
+		'tags' => 'My labels',	//TODO - Translation
+		'unread' => 'Show only unread',	//TODO - Translation
 	),
 	),
 	'share' => 'Share',
 	'share' => 'Share',
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Article tags',	//TODO
+		'related' => 'Article tags',	//TODO - Translation
 	),
 	),
 );
 );

+ 11 - 3
app/i18n/ru/install.php

@@ -24,8 +24,8 @@ return array(
 			'ok' => 'Конфигурация базы данных сохранена.',
 			'ok' => 'Конфигурация базы данных сохранена.',
 		),
 		),
 		'host' => 'Хост',
 		'host' => 'Хост',
-		'prefix' => 'Префикс таблицы',
 		'password' => 'Пароль базы данных',
 		'password' => 'Пароль базы данных',
+		'prefix' => 'Префикс таблицы',
 		'type' => 'Тип базы данных',
 		'type' => 'Тип базы данных',
 		'username' => 'Имя пользователя базы данных',
 		'username' => 'Имя пользователя базы данных',
 	),
 	),
@@ -64,9 +64,13 @@ return array(
 			'nok' => 'Убедитесь, что вы не изменяете ваш HTTP REFERER.',
 			'nok' => 'Убедитесь, что вы не изменяете ваш HTTP REFERER.',
 			'ok' => 'Ваш HTTP REFERER известен и соотвествует вашему серверу.',
 			'ok' => 'Ваш HTTP REFERER известен и соотвествует вашему серверу.',
 		),
 		),
+		'json' => array(
+			'nok' => 'Cannot find a recommended library to parse JSON.',	//TODO - Translation
+			'ok' => 'You have a recommended library to parse JSON.',	//TODO - Translation
+		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO
-			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	//TODO - Translation
+			'ok' => 'You have the recommended library mbstring for Unicode.',	//TODO - Translation
 		),
 		),
 		'minz' => array(
 		'minz' => array(
 			'nok' => 'У вас не установлен фрейворк Minz.',
 			'nok' => 'У вас не установлен фрейворк Minz.',
@@ -88,6 +92,10 @@ return array(
 			'nok' => 'Проверьте права доступа к папке <em>./data/users</em> . Сервер HTTP должен иметь права на запись в эту папку.',
 			'nok' => 'Проверьте права доступа к папке <em>./data/users</em> . Сервер HTTP должен иметь права на запись в эту папку.',
 			'ok' => 'Права на папку users  в порядке.',
 			'ok' => 'Права на папку users  в порядке.',
 		),
 		),
+		'xml' => array(
+			'nok' => 'Cannot find the required library to parse XML.',
+			'ok' => 'You have the required library to parse XML.',
+		),
 	),
 	),
 	'conf' => array(
 	'conf' => array(
 		'_' => 'Общие настройки',
 		'_' => 'Общие настройки',

+ 69 - 62
app/i18n/ru/sub.php

@@ -2,85 +2,92 @@
 
 
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',// TODO
-		'title' => 'API',// TODO
+		'documentation' => 'Copy the following URL to use it within an external tool.',	//TODO - Translation
+		'title' => 'API',	//TODO - Translation
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
-		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',// TODO
-		'label' => 'Subscribe',// TODO
-		'title' => 'Bookmarklet',// TODO
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click "Subscribe" button in any page you want to subscribe to.',	//TODO - Translation
+		'label' => 'Subscribe',	//TODO - Translation
+		'title' => 'Bookmarklet',	//TODO - Translation
 	),
 	),
 	'category' => array(
 	'category' => array(
-		'_' => 'Category',// TODO
-		'add' => 'Add a category',// TODO
-		'empty' => 'Empty category',// TODO
-		'new' => 'New category',// TODO
+		'_' => 'Category',	//TODO - Translation
+		'add' => 'Add a category',	//TODO - Translation
+		'empty' => 'Empty category',	//TODO - Translation
+		'new' => 'New category',	//TODO - Translation
 	),
 	),
 	'feed' => array(
 	'feed' => array(
-		'add' => 'Add a RSS feed',// TODO
-		'advanced' => 'Advanced',// TODO
-		'archiving' => 'Archivage',// TODO
+		'add' => 'Add a RSS feed',	//TODO - Translation
+		'advanced' => 'Advanced',	//TODO - Translation
+		'archiving' => 'Archivage',	//TODO - Translation
 		'auth' => array(
 		'auth' => array(
-			'configuration' => 'Login',// TODO
-			'help' => 'Connection allows to access HTTP protected RSS feeds',// TODO
-			'http' => 'HTTP Authentication',// TODO
-			'password' => 'HTTP password',// TODO
-			'username' => 'HTTP username',// TODO
+			'configuration' => 'Login',	//TODO - Translation
+			'help' => 'Connection allows to access HTTP protected RSS feeds',	//TODO - Translation
+			'http' => 'HTTP Authentication',	//TODO - Translation
+			'password' => 'HTTP password',	//TODO - Translation
+			'username' => 'HTTP username',	//TODO - Translation
 		),
 		),
-		'clear_cache' => 'Always clear cache',	//TODO
-		'css_help' => 'Retrieves truncated RSS feeds (caution, requires more time!)',// TODO
-		'css_path' => 'Articles CSS path on original website',// TODO
-		'description' => 'Description',// TODO
-		'empty' => 'This feed is empty. Please verify that it is still maintained.',// TODO
-		'error' => 'This feed has encountered a problem. Please verify that it is always reachable then actualize it.',// TODO
-		'informations' => 'Information',// TODO
-		'keep_history' => 'Minimum number of articles to keep',// TODO
-		'moved_category_deleted' => 'When you delete a category, its feeds are automatically classified under <em>%s</em>.',// TODO
-		'mute' => 'mute', // TODO
-		'no_selected' => 'No feed selected.',// TODO
-		'number_entries' => '%d articles',// TODO
+		'clear_cache' => 'Always clear cache',	//TODO - Translation
+		'css_help' => 'Retrieves truncated RSS feeds (caution, requires more time!)',	//TODO - Translation
+		'css_path' => 'Articles CSS path on original website',	//TODO - Translation
+		'description' => 'Description',	//TODO - Translation
+		'empty' => 'This feed is empty. Please verify that it is still maintained.',	//TODO - Translation
+		'error' => 'This feed has encountered a problem. Please verify that it is always reachable then actualize it.',	//TODO - Translation
+		'informations' => 'Information',	//TODO - Translation
+		'keep_history' => 'Minimum number of articles to keep',	//TODO - Translation
+		'moved_category_deleted' => 'When you delete a category, its feeds are automatically classified under <em>%s</em>.',	//TODO - Translation
+		'mute' => 'mute',	//TODO - Translation
+		'no_selected' => 'No feed selected.',	//TODO - Translation
+		'number_entries' => '%d articles',	//TODO - Translation
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility', // TODO
-			'archived' => 'Do not show (archived)', // TODO
-			'main_stream' => 'Show in main stream', // TODO
-			'normal' => 'Show in its category', // TODO
+			'_' => 'Visibility',	//TODO - Translation
+			'archived' => 'Do not show (archived)',	//TODO - Translation
+			'main_stream' => 'Show in main stream',	//TODO - Translation
+			'normal' => 'Show in its category',	//TODO - Translation
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	//TODO
-		'stats' => 'Statistics',// TODO
-		'think_to_add' => 'You may add some feeds.',// TODO
-		'timeout' => 'Timeout in seconds',	//TODO
-		'title' => 'Title',// TODO
-		'title_add' => 'Add a RSS feed',// TODO
-		'ttl' => 'Do not automatically refresh more often than',// TODO
-		'url' => 'Feed URL',// TODO
-		'validator' => 'Check the validity of the feed',// TODO
-		'website' => 'Website URL',// TODO
-		'pubsubhubbub' => 'Instant notification with PubSubHubbub',// TODO
+		'websub' => 'Instant notification with WebSub',	//TODO - Translation
+		'show' => array(
+			'all' => 'Show all feeds',	//TODO - Translation
+			'error' => 'Show only feeds with error',	//TODO - Translation
+		),
+		'showing' => array(
+			'error' => 'Showing only feeds with error',	//TODO - Translation
+		),
+		'ssl_verify' => 'Verify SSL security',	//TODO - Translation
+		'stats' => 'Statistics',	//TODO - Translation
+		'think_to_add' => 'You may add some feeds.',	//TODO - Translation
+		'timeout' => 'Timeout in seconds',	//TODO - Translation
+		'title' => 'Title',	//TODO - Translation
+		'title_add' => 'Add a RSS feed',	//TODO - Translation
+		'ttl' => 'Do not automatically refresh more often than',	//TODO - Translation
+		'url' => 'Feed URL',	//TODO - Translation
+		'validator' => 'Check the validity of the feed',	//TODO - Translation
+		'website' => 'Website URL',	//TODO - Translation
 	),
 	),
 	'firefox' => array(
 	'firefox' => array(
-		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',// TODO
-		'title' => 'Firefox feed reader',// TODO
+		'documentation' => 'Follow the steps described <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">here</a> to add FreshRSS to Firefox feed reader list.',	//TODO - Translation
+		'title' => 'Firefox feed reader',	//TODO - Translation
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
-		'export' => 'Export',// TODO
-		'export_opml' => 'Export list of feeds (OPML)',// TODO
-		'export_starred' => 'Export your favourites',// TODO
-		'feed_list' => 'List of %s articles',// TODO
-		'file_to_import' => 'File to import<br />(OPML, JSON or ZIP)',// TODO
-		'file_to_import_no_zip' => 'File to import<br />(OPML or JSON)',// TODO
-		'import' => 'Import',// TODO
-		'starred_list' => 'List of favourite articles',// TODO
-		'title' => 'Import / export',// TODO
+		'export' => 'Export',	//TODO - Translation
+		'export_opml' => 'Export list of feeds (OPML)',	//TODO - Translation
+		'export_starred' => 'Export your favourites',	//TODO - Translation
+		'feed_list' => 'List of %s articles',	//TODO - Translation
+		'file_to_import' => 'File to import<br />(OPML, JSON or ZIP)',	//TODO - Translation
+		'file_to_import_no_zip' => 'File to import<br />(OPML or JSON)',	//TODO - Translation
+		'import' => 'Import',	//TODO - Translation
+		'starred_list' => 'List of favourite articles',	//TODO - Translation
+		'title' => 'Import / export',	//TODO - Translation
 	),
 	),
 	'menu' => array(
 	'menu' => array(
-		'bookmark' => 'Subscribe (FreshRSS bookmark)',// TODO
-		'import_export' => 'Import / export',// TODO
-		'subscription_management' => 'Subscriptions management',// TODO
-		'subscription_tools' => 'Subscription tools',// TODO
+		'bookmark' => 'Subscribe (FreshRSS bookmark)',	//TODO - Translation
+		'import_export' => 'Import / export',	//TODO - Translation
+		'subscription_management' => 'Subscriptions management',	//TODO - Translation
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 	'title' => array(
 	'title' => array(
-		'_' => 'Subscriptions management',// TODO
-		'feed_management' => 'RSS feeds management',// TODO
-		'subscription_tools' => 'Subscription tools',// TODO
+		'_' => 'Subscriptions management',	//TODO - Translation
+		'feed_management' => 'RSS feeds management',	//TODO - Translation
+		'subscription_tools' => 'Subscription tools',	//TODO - Translation
 	),
 	),
 );
 );

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff