diff options
| author | 2018-12-22 13:22:20 +0100 | |
|---|---|---|
| committer | 2018-12-22 13:22:20 +0100 | |
| commit | f0a359619fa2936d66a2b96dd086d4686e7405fa (patch) | |
| tree | ddad42a7f6813bd458f39d5203d083daad4cc1c5 | |
| parent | e04804d0f67dd43fd3f072b9a127768ee7b7b56c (diff) | |
| parent | 4a1a852f457d52fa47191e3f7e3e9073e1324cd9 (diff) | |
Merge pull request #2186 from FreshRSS/dev1.13.0
FreshRSS 1.13.0
190 files changed, 4979 insertions, 4020 deletions
diff --git a/.dockerignore b/.dockerignore index ab223517d..fa42e0e9c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,3 @@ -*/.git -*/data -*/docs +**/.git/ +**/data/ +**/docs/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f9923d03..f2ca6f13b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,52 @@ # 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 * Features @@ -25,6 +72,7 @@ * Deployment * 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) + * Docker image updated to Alpine 3.8.1 with PHP 7.2.8 and Apache 2.4.34 * Bug fixing * 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) diff --git a/CREDITS.md b/CREDITS.md index 9d3c07c0e..83bb97a25 100644 --- a/CREDITS.md +++ b/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) * [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 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/) * [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) @@ -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) * [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 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) * [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) * [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) * [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) * [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) diff --git a/Docker/README.md b/Docker/README.md index f2aa3db20..6b3871c6b 100644 --- a/Docker/README.md +++ b/Docker/README.md @@ -1,7 +1,6 @@ # 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 @@ -10,9 +9,10 @@ curl -fsSL https://get.docker.com/ -o get-docker.sh sh get-docker.sh ``` + ## Optional: Build Docker image of FreshRSS 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 # First time only @@ -24,53 +24,111 @@ sudo docker pull alpine:3.8 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 -# 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 \ - -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 -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 \ - -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 ``` -#### 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 -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 \ - -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 # 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 rename freshrss freshrss_old # 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 sudo docker rm freshrss_old ``` -## Command line + +## Debugging ```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 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 -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). 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'`. Not passing the `CRON_MIN` environment variable – or setting it to empty string – will disable the cron daemon. ```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' \ - -p 8080:80 \ --name freshrss freshrss/freshrss ``` @@ -129,32 +195,15 @@ See cron option 1 for customising the cron schedule. ```sh 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' \ + --net freshrss-network \ --name freshrss_cron freshrss/freshrss \ 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/) @@ -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. * 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 -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; + } +} ``` diff --git a/LICENSE.txt b/LICENSE.txt index 42c1fcaf1..42c1fcaf1 100755..100644 --- a/LICENSE.txt +++ b/LICENSE.txt diff --git a/README.fr.md b/README.fr.md index 312fbac45..e40ab8296 100644 --- a/README.fr.md +++ b/README.fr.md @@ -1,4 +1,5 @@ -[![Build Status][travis-badge]][travis-link] +[](https://travis-ci.org/FreshRSS/FreshRSS) +[](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. * [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 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). + +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. +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 * Démo : http://demo.freshrss.org/ * Licence : [GNU AGPL 3](https://www.gnu.org/licenses/agpl-3.0.fr.html)  -# 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 ! + -# 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 +* 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 * 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) -* 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) * 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+ -* Un navigateur Web récent tel que Firefox / IceCat, Internet Explorer 11 / Edge, Chromium / Chrome, Opera, Safari. - * Fonctionne aussi sur mobile - -# 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 automatisée +* [](./Docker/) +* [](https://install-app.yunohost.org/?app=freshrss) +* [](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) 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/` @@ -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). -## Installation automatisée -* [](./Docker/) -* [](https://install-app.yunohost.org/?app=freshrss) -* [](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 # Si vous utilisez le serveur Web Apache (sinon il faut un autre serveur Web) 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 ``` - -# 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/`. * 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. @@ -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. +# 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 * 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) @@ -157,7 +173,7 @@ Voir le [dépôt dédié à ces extensions](https://github.com/FreshRSS/Extensio # 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 @@ -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/)) * GNU/Linux * [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Libre) +* MacOS + * [Vienna RSS](http://www.vienna-rss.com/) (Libre) ## 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/) * [jQuery](https://jquery.com/) * [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/) * [flotr2](http://www.humblesoftware.com/flotr2) -## Uniquement pour certaines options +## Uniquement pour certaines options ou configurations * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [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) * [password_compat](https://github.com/ircmaxell/password_compat) + @@ -1,70 +1,82 @@ [![Build Status][travis-badge]][travis-link] +[](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. * [Version française](README.fr.md) # 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). + +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. +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 * Demo: https://demo.freshrss.org/ * License: [GNU AGPL 3](https://www.gnu.org/licenses/agpl-3.0.html)  -# 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! + -# 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 +* 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 * 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) -* 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) - * 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+ -* A recent browser like Firefox / IceCat, Internet Explorer 11 / Edge, Chromium / Chrome, Opera, Safari. - * Works on mobile - -# 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) + +## Automated install +* [](./Docker/) +* [](https://install-app.yunohost.org/?app=freshrss) +* [](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) -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 * 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. -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://install-app.yunohost.org/?app=freshrss) -* [](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 # If you use an Apache Web server (otherwise you need another Web server) 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). ## 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) * In that case, create a `./p/i/.htaccess` file with a matching `.htpasswd` file. ## Automatic feed update * 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)…). -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: ``` @@ -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 ``` - -# 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. -* 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. * 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 * 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) @@ -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/)) * GNU/Linux * [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Open source) +* MacOS + * [Vienna RSS](http://www.vienna-rss.com/) (Open source) ## Fever API @@ -192,15 +210,12 @@ Supported clients are: * [php-http-304](https://alexandre.alapetite.fr/doc-alex/php-http-304/) * [jQuery](https://jquery.com/) * [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/) * [flotr2](http://www.humblesoftware.com/flotr2) -## Only for some options +## Only for some options or configurations * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [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) * [password_compat](https://github.com/ircmaxell/password_compat) diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index 20bcd2e76..9c3900f39 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -308,6 +308,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { * - user limit (default: 1) * - user category limit (default: 16384) * - user feed limit (default: 16384) + * - user login duration for form auth (default: 2592000) */ public function systemAction() { 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_feeds'] = Minz_Request::param('max-feeds', 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->title = Minz_Request::param('instance-name', 'FreshRSS'); FreshRSS_Context::$system_conf->auto_update_url = Minz_Request::param('auto-update-url', false); diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index f2b1b8960..74c9eacfa 100755 --- a/app/Controllers/feedController.php +++ b/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); $date_min = time() - (3600 * 24 * 30 * $nb_month_old); - // PubSubHubbub support + // WebSub (PubSubHubbub) support $pubsubhubbubEnabledGeneral = FreshRSS_Context::$system_conf->pubsubhubbub_enabled; $pshbMinAge = time() - (3600 * 24); //TODO: Make a configuration. @@ -437,13 +437,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $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 $selfUrl = checkUrl($feed->selfUrl()); if ($selfUrl) { - Minz_Log::debug('PubSubHubbub unsubscribe ' . $feed->url(false)); + Minz_Log::debug('WebSub unsubscribe ' . $feed->url(false)); 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); 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(); 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 - Minz_Log::warning('Error while PubSubHubbub subscribing to ' . $feed->url(false)); + Minz_Log::warning('Error while WebSub subscribing to ' . $feed->url(false)); } } $feed->unlock(); diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 0fb5ba651..2d8d4e01d 100644 --- a/app/Controllers/importExportController.php +++ b/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; } @@ -165,17 +176,22 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { private static function guessFileType($filename) { if (substr_compare($filename, '.zip', -4) === 0) { return 'zip'; - } elseif (substr_compare($filename, '.opml', -5) === 0 || - substr_compare($filename, '.xml', -4) === 0) { + } elseif (substr_compare($filename, '.opml', -5) === 0) { return 'opml'; - } elseif (substr_compare($filename, '.json', -5) === 0 && - strpos($filename, 'starred') !== false) { - return 'json_starred'; } 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; } + 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). * @@ -405,7 +458,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { // Oops, no more place! Minz_Log::warning(_t('feedback.sub.feed.over_max', $limits['max_feeds'])); } else { - $feed = $this->addFeedJson($item['origin'], $google_compliant); + $feed = $this->addFeedJson($item['origin']); } 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. $existingHashForGuids = array(); foreach ($newFeedGuids as $feedId => $newGuids) { @@ -443,19 +505,36 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $feed_id = $article_to_feed[$item['id']]; $author = isset($item['author']) ? $item['author'] : ''; - $key_content = ($google_compliant && !isset($item['content'])) ? 'summary' : 'content'; + $is_starred = $starred; $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( $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->_tags($tags); @@ -478,8 +557,21 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } else { $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(); @@ -488,6 +580,20 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $this->feedDAO->updateCachedValues(); $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; } @@ -495,16 +601,24 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { * This method import a JSON-based feed (Google Reader format). * * @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, * else null. */ - private function addFeedJson($origin, $google_compliant) { + private function addFeedJson($origin) { $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 { // 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. $filename = key($export_files); $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; } @@ -683,7 +797,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } // 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->open($zip_file, ZipArchive::OVERWRITE); @@ -696,7 +810,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { header('Content-Type: application/zip'); header('Content-Length: ' . filesize($zip_file)); $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); unlink($zip_file); } diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index 0b1439ba5..46503fc19 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -33,6 +33,8 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { @filemtime(PUBLIC_PATH . '/scripts/category.js'))); Minz_View::prependTitle(_t('sub.title') . ' · '); + $this->view->onlyFeedsWithError = Minz_Request::paramTernary('error'); + $id = Minz_Request::param('id'); if ($id !== false) { $feedDAO = FreshRSS_Factory::createFeedDao(); diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 8c711308c..9c3e31952 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -233,9 +233,11 @@ class FreshRSS_FormAuth { $token_file = DATA_PATH . '/tokens/' . $token . '.txt'; $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); return array(); } @@ -256,7 +258,7 @@ class FreshRSS_FormAuth { } $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; Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire); return $token; @@ -277,7 +279,7 @@ class FreshRSS_FormAuth { public static function purgeTokens() { $conf = Minz_Configuration::get('system'); $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; foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) { // $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7 diff --git a/app/Models/BooleanSearch.php b/app/Models/BooleanSearch.php index 6e016f7e9..88eeea73c 100644 --- a/app/Models/BooleanSearch.php +++ b/app/Models/BooleanSearch.php @@ -45,6 +45,14 @@ class FreshRSS_BooleanSearch { return $this->searches; } + public function add($search) { + if ($search instanceof FreshRSS_Search) { + $this->searches[] = $search; + return $search; + } + return null; + } + public function __toString() { return $this->getRawInput(); } diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php index ad703dfc5..ec6380df4 100644 --- a/app/Models/ConfigurationSetter.php +++ b/app/Models/ConfigurationSetter.php @@ -335,6 +335,9 @@ class FreshRSS_ConfigurationSetter { private function _limits(&$data, $values) { $max_small_int = 16384; $limits_keys = array( + 'cookie_duration' => array( + 'min' => 0, + ), 'cache_duration' => array( 'min' => 0, ), diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index a01c2227b..6d77a33cd 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -671,6 +671,15 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { 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) { 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)); } - 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->execute($values); diff --git a/app/Models/Feed.php b/app/Models/Feed.php index e1dd2990d..b21a8bbbe 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -424,7 +424,7 @@ class FreshRSS_Feed extends Minz_Model { $author_names = ''; if (is_array($authors)) { 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); @@ -498,7 +498,7 @@ class FreshRSS_Feed extends Minz_Model { @unlink($this->lockPath); } - //<PubSubHubbub> + //<WebSub> public function pubSubHubbubEnabled() { $url = $this->selfUrl ? $this->selfUrl : $this->url; @@ -534,13 +534,13 @@ class FreshRSS_Feed extends Minz_Model { if ($hubFile = @file_get_contents($hubFilename)) { $hubJson = json_decode($hubFile, true); 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, PSHB_LOG); return false; } 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']) . ' and needs renewal: ' . $this->url; Minz_Log::warning($text); @@ -560,7 +560,7 @@ class FreshRSS_Feed extends Minz_Model { file_put_contents($hubFilename, json_encode($hubJson)); @mkdir(PSHB_PATH . '/keys/'); 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, PSHB_LOG); } @@ -579,17 +579,17 @@ class FreshRSS_Feed extends Minz_Model { $hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($url) . '/!hub.json'; $hubFile = @file_get_contents($hubFilename); 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; } $hubJson = json_decode($hubFile, true); 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; } $callbackUrl = checkUrl(Minz_Request::getBaseUrl() . '/api/pshb.php?k=' . $hubJson['key']); if ($callbackUrl == '') { - Minz_Log::warning('Invalid callback for PubSubHubbub: ' . $this->url); + Minz_Log::warning('Invalid callback for WebSub: ' . $this->url); return false; } if (!$state) { //unsubscribe @@ -618,7 +618,8 @@ class FreshRSS_Feed extends Minz_Model { $response = curl_exec($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); if (substr($info['http_code'], 0, 1) == '2') { @@ -633,5 +634,5 @@ class FreshRSS_Feed extends Minz_Model { return false; } - //</PubSubHubbub> + //</WebSub> } diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index e579f5881..7f00642f4 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -465,9 +465,15 @@ UPDATE `{$this->prefix}feed` SQL; $stm = $this->bd->prepare($sql); 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 $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 { $stm->execute(array(':new_value' => -3600, ':old_value' => -1)); } diff --git a/app/Models/Search.php b/app/Models/Search.php index c52e391fa..f9cda7354 100644 --- a/app/Models/Search.php +++ b/app/Models/Search.php @@ -73,10 +73,18 @@ class FreshRSS_Search { return $this->min_date; } + public function setMinDate($value) { + return $this->min_date = $value; + } + public function getMaxDate() { return $this->max_date; } + public function setMaxDate($value) { + return $this->max_date = $value; + } + public function getMinPubdate() { return $this->min_pubdate; } diff --git a/app/Models/TagDAO.php b/app/Models/TagDAO.php index 1b59c8971..b55d2b35d 100644 --- a/app/Models/TagDAO.php +++ b/app/Models/TagDAO.php @@ -266,7 +266,7 @@ class FreshRSS_TagDAO extends Minz_ModelPdo implements FreshRSS_Searchable { if (is_array($entries) && count($entries) > 0) { $sql .= ' AND et.id_entry IN (' . str_repeat('?,', count($entries) - 1). '?)'; foreach ($entries as $entry) { - $values[] = $entry->id(); + $values[] = is_array($entry) ? $entry['id'] : $entry->id(); } } $stm = $this->bd->prepare($sql); diff --git a/app/i18n/cz/admin.php b/app/i18n/cz/admin.php index 78a4a52e4..68127f571 100644 --- a/app/i18n/cz/admin.php +++ b/app/i18n/cz/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => 'Máte rozšíření JSON.', ), '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( 'nok' => 'Nemáte framework Minz.', @@ -106,16 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Author', //TODO - Translation + 'community' => 'Available community extensions', //TODO - Translation + 'description' => 'Description', //TODO - Translation 'disabled' => 'Vypnuto', 'empty_list' => 'Není naistalováno žádné rozšíření', 'enabled' => 'Zapnuto', + 'latest' => 'Installed', //TODO - Translation + 'name' => 'Name', //TODO - Translation 'no_configure_view' => 'Toto rozšíření nemá žádné možnosti nastavení.', 'system' => array( '_' => 'Systémová rozšíření', 'no_rights' => 'Systémová rozšíření (na ně nemáte oprávnění)', ), 'title' => 'Rozšíření', + 'update' => 'Update available', //TODO - Translation 'user' => 'Uživatelská rozšíření', + 'version' => 'Version', //TODO - Translation ), 'stats' => array( '_' => 'Statistika', @@ -150,22 +157,19 @@ return array( 'top_feed' => 'Top ten kanálů', ), '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( 'help' => '0 znamená žádná omezení účtu', '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( '_' => 'Aktualizace systému', @@ -179,15 +183,15 @@ return array( 'user' => array( 'articles_and_size' => '%s článků (%s)', 'create' => 'Vytvořit nového uživatele', - 'delete_users' => 'Delete user', // TODO + 'delete_users' => 'Delete user', //TODO - Translation 'language' => 'Jazyk', 'number' => 'Zatím je vytvořen %d účet', 'numbers' => 'Zatím je vytvořeno %d účtů', 'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>', 'password_format' => 'Alespoň 7 znaků', - 'selected' => 'Selected user', // TODO + 'selected' => 'Selected user', //TODO - Translation 'title' => 'Správa uživatelů', - 'update_users' => 'Update user', // TODO + 'update_users' => 'Update user', //TODO - Translation 'user_list' => 'Seznam uživatelů', 'username' => 'Přihlašovací jméno', 'users' => 'Uživatelé', diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php index 84ee78c73..d0203c252 100644 --- a/app/i18n/cz/conf.php +++ b/app/i18n/cz/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => 'Spodní řádek', 'entry' => 'Ikony článků', 'publication_date' => 'Datum vydání', - 'related_tags' => 'Související tagy', //TODO + 'related_tags' => 'Související tagy', //TODO - Translation 'sharing' => 'Sdílení', 'top_line' => 'Horní řádek', ), @@ -28,6 +28,7 @@ return array( 'seconds' => 'sekund (0 znamená žádný timeout)', 'timeout' => 'Timeout HTML5 notifikací', ), + 'show_nav_buttons' => 'Show the navigation buttons', //TODO - Translation 'theme' => 'Vzhled', 'title' => 'Zobrazení', 'width' => array( @@ -37,12 +38,22 @@ return array( 'no_limit' => 'Bez limitu', '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( '_' => 'Uživatelské dotazy', '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:', 'get_all' => 'Zobrazit všechny články', 'get_category' => 'Zobrazit "%s" kategorii', @@ -53,7 +64,7 @@ return array( 'number' => 'Dotaz n°%d', 'order_asc' => 'Zobrazit nejdříve nejstarší č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"', 'state_0' => 'Zobrazit všechny články', 'state_1' => 'Zobrazit přečtené články', @@ -73,31 +84,19 @@ return array( 'state_15' => 'Zobrazit všechny články', '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( '_' => 'Čtení', 'after_onread' => 'Po “označit vše jako přečtené”,', 'articles_per_page' => 'Počet článků na stranu', 'auto_load_more' => 'Načítat další články dole na stránce', '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é”', '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é', '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ů', - '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)', + '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.', 'read' => array( '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', 'unread' => 'Zobrazit jen nepřečtené', ), + 'sides_close_article' => 'Clicking outside of article text area closes the article', //TODO - Translation 'sort' => array( '_' => 'Řazení', 'newer_first' => 'Nejdříve nejnovější', @@ -128,7 +128,7 @@ return array( ), 'sharing' => array( '_' => 'Sdílení', - 'add' => 'Add a sharing method', // TODO + 'add' => 'Add a sharing method', //TODO - Translation 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -136,7 +136,7 @@ return array( 'g+' => 'Google+', 'more_information' => 'Více informací', 'print' => 'Tisk', - 'remove' => 'Remove sharing method', // TODO + 'remove' => 'Remove sharing method', //TODO - Translation 'shaarli' => 'Shaarli', 'share_name' => 'Jméno pro zobrazení', 'share_url' => 'Jakou URL použít pro sdílení', @@ -153,27 +153,30 @@ return array( 'collapse_article' => 'Srolovat', 'first_article' => 'Skočit na první článek', 'focus_search' => 'Hledání', - 'global_view' => 'Switch to global view', // TODO + 'global_view' => 'Switch to global view', //TODO - Translation 'help' => 'Zobrazit documentaci', 'javascript' => 'Pro použití zkratek musí být povolen JavaScript', 'last_article' => 'Skočit na poslední článek', 'load_more' => 'Načíst více článků', - 'mark_read' => 'Označit jako přečtené', 'mark_favorite' => 'Označit jako oblíbené', + 'mark_read' => 'Označit jako přečtené', '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_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation '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', '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', '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', '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.', - 'views' => 'Views', // TODO + 'views' => 'Views', //TODO - Translation ), 'user' => array( 'articles_and_size' => '%s článků (%s)', diff --git a/app/i18n/cz/feedback.php b/app/i18n/cz/feedback.php index fe85a3599..3d0dcbc96 100644 --- a/app/i18n/cz/feedback.php +++ b/app/i18n/cz/feedback.php @@ -50,11 +50,15 @@ return array( 'no_zip_extension' => 'Na serveru není naistalována podpora ZIP.', '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( 'actualize' => 'Aktualizovat', '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( '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>', 'deleted' => 'Kanál byl smazán', '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é', 'n_actualized' => '%d kanálů bylo aktualizováno', 'n_entries_deleted' => '%d článků bylo smazáno', @@ -105,12 +109,8 @@ return array( 'error' => 'Uživatele %s nelze smazat', ), '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', - ), ); diff --git a/app/i18n/cz/gen.php b/app/i18n/cz/gen.php index b9a65f210..08fce0280 100644 --- a/app/i18n/cz/gen.php +++ b/app/i18n/cz/gen.php @@ -19,7 +19,7 @@ return array( 'see_website' => 'Navštívit WWW stránku', 'submit' => 'Odeslat', 'truncate' => 'Smazat všechny články', - 'update' => 'Update', // TODO + 'update' => 'Update', //TODO - Translation ), 'auth' => array( 'email' => 'Email', @@ -44,33 +44,28 @@ return array( ), 'date' => array( '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', 'april' => 'Dub', + 'Aug' => '\\S\\r\\p\\e\\n', 'aug' => 'srp', 'august' => 'Srp', 'before_yesterday' => 'Předevčírem', + 'Dec' => '\\P\\r\\o\\s\\i\\n\\e\\c', 'dec' => 'pro', 'december' => 'Pro', + 'Feb' => '\\Ú\\n\\o\\r', 'feb' => 'úno', 'february' => 'Úno', 'format_date' => 'j\\. %s Y', 'format_date_hour' => 'j\\. %s Y \\v H\\:i', 'fri' => 'Pá', + 'Jan' => '\\L\\e\\d\\e\\n', 'jan' => 'led', 'january' => 'Led', + 'Jul' => '\\Č\\e\\r\\v\\e\\n\\e\\c', 'jul' => 'čvn', 'july' => 'Čvn', + 'Jun' => '\\Č\\e\\r\\v\\e\\n', 'jun' => 'čer', 'june' => 'Čer', 'last_3_month' => 'Minulé tři měsíce', @@ -78,17 +73,22 @@ return array( 'last_month' => 'Minulý měsíc', 'last_week' => 'Minulý týden', 'last_year' => 'Minulý rok', + 'Mar' => '\\B\\ř\\e\\z\\e\\n', 'mar' => 'bře', 'march' => 'Bře', + 'May' => '\\K\\v\\ě\\t\\e\\n', 'may' => 'Květen', 'may_' => 'Kvě', 'mon' => 'Po', 'month' => 'měsíce', + 'Nov' => '\\L\\i\\s\\t\\o\\p\\a\\d', 'nov' => 'lis', 'november' => 'Lis', + 'Oct' => '\\Ř\\í\\j\\e\\n', 'oct' => 'říj', 'october' => 'Říj', 'sat' => 'So', + 'Sep' => '\\Z\\á\\ř\\í', 'sep' => 'zář', 'september' => 'Zář', 'sun' => 'Ne', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -145,7 +146,7 @@ return array( 'sharing' => 'Sdílení', 'shortcuts' => 'Zkratky', 'stats' => 'Statistika', - 'system' => 'System configuration', // @todo translate + 'system' => 'System configuration', //TODO - Translation 'update' => 'Aktualizace', 'user_management' => 'Správa uživatelů', 'user_profile' => 'Profil', @@ -160,7 +161,6 @@ return array( 'previous' => 'Předchozí', ), 'share' => array( - 'Known' => 'Known based sites', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Known based sites', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Tisk', 'shaarli' => 'Shaarli', @@ -186,6 +188,7 @@ return array( 'damn' => 'Sakra!', 'default_category' => 'Nezařazeno', 'no' => 'Ne', + 'not_applicable' => 'Not available', //TODO - Translation 'ok' => 'Ok!', 'or' => 'nebo', 'yes' => 'Ano', diff --git a/app/i18n/cz/index.php b/app/i18n/cz/index.php index 7e60ca379..00f424fe8 100644 --- a/app/i18n/cz/index.php +++ b/app/i18n/cz/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => 'Označit vše jako přečtené', 'mark_cat_read' => 'Označit kategorii jako přečtenou', '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', 'non-starred' => 'Zobrazit vše vyjma oblíbených', 'normal_view' => 'Normální', @@ -53,11 +53,11 @@ return array( 'starred' => 'Zobrazit oblíbené', 'stats' => 'Statistika', 'subscription' => 'Správa subskripcí', - 'tags' => 'My labels', //TODO + 'tags' => 'My labels', //TODO - Translation 'unread' => 'Zobrazovat nepřečtené', ), 'share' => 'Sdílet', 'tag' => array( - 'related' => 'Související tagy', //TODO + 'related' => 'Související tagy', //TODO - Translation ), ); diff --git a/app/i18n/cz/install.php b/app/i18n/cz/install.php index acdb48ab6..d1b5d1616 100644 --- a/app/i18n/cz/install.php +++ b/app/i18n/cz/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'Nastavení databáze bylo uloženo.', ), 'host' => 'Hostitel', - 'prefix' => 'Prefix tabulky', 'password' => 'Heslo', + 'prefix' => 'Prefix tabulky', 'type' => 'Typ databáze', 'username' => 'Uživatel', ), @@ -45,7 +45,7 @@ return array( 'ok' => 'Máte rozšíření cURL.', ), '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.', ), 'dom' => array( @@ -69,8 +69,8 @@ return array( 'ok' => 'Máte doporučenou knihovnu pro parsování JSON.', ), '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( 'nok' => 'Nemáte framework Minz.', diff --git a/app/i18n/cz/sub.php b/app/i18n/cz/sub.php index 55441aaf8..ad02f6f49 100644 --- a/app/i18n/cz/sub.php +++ b/app/i18n/cz/sub.php @@ -2,13 +2,13 @@ return 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 - '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( '_' => 'Kategorie', @@ -27,7 +27,7 @@ return array( 'password' => 'Heslo', '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_path' => 'Původní CSS soubor článku z webových stránek', 'description' => 'Popis', @@ -36,30 +36,37 @@ return array( 'informations' => 'Informace', '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>.', - 'mute' => 'mute', // TODO + 'mute' => 'mute', //TODO - Translation 'no_selected' => 'Nejsou označeny žádné kanály.', 'number_entries' => '%d článků', '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”', - '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', 'think_to_add' => 'Můžete přidat kanály.', - 'timeout' => 'Timeout in seconds', //TODO + 'timeout' => 'Timeout in seconds', //TODO - Translation 'title' => 'Název', 'title_add' => 'Přidat RSS kanál', 'ttl' => 'Neobnovovat častěji než', 'url' => 'URL kanálu', 'validator' => 'Zkontrolovat platnost kanálu', 'website' => 'URL webové stránky', - 'pubsubhubbub' => 'Okamžité oznámení s 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 - 'title' => 'Firefox feed reader',// TODO + 'title' => 'Firefox feed reader', //TODO - Translation ), 'import_export' => array( 'export' => 'Export', @@ -76,11 +83,11 @@ return array( 'bookmark' => 'Přihlásit (FreshRSS bookmark)', 'import_export' => 'Import / export', 'subscription_management' => 'Správa subskripcí', - 'subscription_tools' => 'Subscription tools',// TODO + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), 'title' => array( '_' => 'Správa subskripcí', 'feed_management' => 'Správa RSS kanálů', - 'subscription_tools' => 'Subscription tools',// TODO + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), ); diff --git a/app/i18n/de/admin.php b/app/i18n/de/admin.php index 2eb4a69f6..f0307dcab 100644 --- a/app/i18n/de/admin.php +++ b/app/i18n/de/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => 'Sie haben die JSON-Erweiterung.', ), '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( 'nok' => 'Ihnen fehlt das Minz-Framework.', @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Autor', + 'community' => 'Verfügbare Community Erweiterungen', + 'description' => 'Beschreibungen', 'disabled' => 'Deaktiviert', 'empty_list' => 'Es gibt keine installierte Erweiterung.', 'enabled' => 'Aktiviert', + 'latest' => 'Installiert', + 'name' => 'Name', 'no_configure_view' => 'Diese Erweiterung kann nicht konfiguriert werden.', 'system' => array( '_' => 'System-Erweiterungen', 'no_rights' => 'System-Erweiterung (Sie haben keine Berechtigung dafür)', ), 'title' => 'Erweiterungen', + 'update' => 'Update verfügbar', 'user' => 'Benutzer-Erweiterungen', - 'community' => 'Verfügbare Community Erweiterungen', - 'name' => 'Name', 'version' => 'Version', - 'description' => 'Beschreibungen', - 'author' => 'Autor', - 'latest' => 'Installiert', - 'update' => 'Update verfügbar', ), 'stats' => array( '_' => 'Statistiken', @@ -162,6 +162,10 @@ return array( 'instance-name' => 'Dein Reader Name', 'max-categories' => 'Anzahl erlaubter Kategorien 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( 'help' => '0 meint, dass es kein Account Limit gibt', 'number' => 'Maximale Anzahl von Accounts', diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php index 579363cb5..e0beb1ac7 100644 --- a/app/i18n/de/conf.php +++ b/app/i18n/de/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => 'Fußzeile', 'entry' => 'Artikel-Symbole', 'publication_date' => 'Datum der Veröffentlichung', - 'related_tags' => 'Verwandte Tags', //TODO + 'related_tags' => 'Verwandte Tags', 'sharing' => 'Teilen', 'top_line' => 'Kopfzeile', ), @@ -28,6 +28,7 @@ return array( 'seconds' => 'Sekunden (0 bedeutet keine Zeitüberschreitung)', 'timeout' => 'Zeitüberschreitung für HTML5-Benachrichtigung', ), + 'show_nav_buttons' => 'Zeige Navigations-Buttons', 'theme' => 'Erscheinungsbild', 'title' => 'Anzeige', 'width' => array( @@ -37,7 +38,17 @@ return array( 'no_limit' => 'Keine Begrenzung', '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( '_' => 'Benutzerabfragen', @@ -73,31 +84,19 @@ return array( 'state_15' => 'Alle Artikel anzeigen', '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( '_' => 'Lesen', 'after_onread' => 'Nach „Alle als gelesen markieren“,', 'articles_per_page' => 'Anzahl der Artikel pro Seite', 'auto_load_more' => 'Die nächsten Artikel am Seitenende laden', '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', 'display_articles_unfolded' => 'Artikel standardmäßig ausgeklappt 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“)', '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)', + 'mark_updated_article_unread' => 'Markieren Sie aktualisierte Artikel als ungelesen', 'number_divided_when_reader' => 'Geteilt durch 2 in der Lese-Ansicht.', 'read' => array( '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', 'unread' => 'Nur ungelesene zeigen', ), + 'sides_close_article' => 'Klick außerhalb des Artikel-Textes schließt den Artikel', 'sort' => array( '_' => 'Sortierreihenfolge', 'newer_first' => 'Neuere zuerst', @@ -158,10 +158,11 @@ return array( 'javascript' => 'JavaScript muss aktiviert sein, um Tastaturkürzel benutzen zu können', 'last_article' => 'Zum letzten Artikel springen', 'load_more' => 'Weitere Artikel laden', - 'mark_read' => 'Als gelesen markieren', 'mark_favorite' => 'Als Favorit markieren', + 'mark_read' => 'Als gelesen markieren', '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_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation 'next_article' => 'Zum nächsten Artikel springen', 'normal_view' => 'Wechsle zur normalen Ansicht', 'other_action' => 'Andere Aktionen', @@ -170,6 +171,8 @@ return array( 'rss_view' => 'Öffne RSS Ansicht in neuem Tab', 'see_on_website' => 'Auf der Original-Webseite ansehen', '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', '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.', diff --git a/app/i18n/de/feedback.php b/app/i18n/de/feedback.php index dc4f679f9..269069162 100644 --- a/app/i18n/de/feedback.php +++ b/app/i18n/de/feedback.php @@ -50,6 +50,10 @@ return array( 'no_zip_extension' => 'Die ZIP-Erweiterung ist auf Ihrem Server nicht vorhanden.', '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( 'actualize' => 'Aktualisieren', 'articles' => array( @@ -76,7 +80,7 @@ return array( 'already_subscribed' => 'Sie haben <em>%s</em> bereits abonniert', 'deleted' => 'Der Feed ist gelöscht worden', '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', 'n_actualized' => 'Die %d Feeds sind aktualisiert worden', 'n_entries_deleted' => 'Die %d Artikel sind gelöscht worden', @@ -109,8 +113,4 @@ return array( 'error' => 'Benutzer %s wurde nicht aktualisiert', ), ), - 'profile' => array( - 'error' => 'Ihr Profil kann nicht geändert werden', - 'updated' => 'Ihr Profil ist geändert worden', - ), ); diff --git a/app/i18n/de/gen.php b/app/i18n/de/gen.php index 617b2a494..c02a55b2c 100644 --- a/app/i18n/de/gen.php +++ b/app/i18n/de/gen.php @@ -44,33 +44,28 @@ return array( ), 'date' => array( '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', 'april' => 'April', + 'Aug' => '\\A\\u\\g\\u\\s\\t', 'aug' => 'Aug', 'august' => 'August', 'before_yesterday' => 'Ältere Beiträge', + 'Dec' => '\\D\\e\\z\\e\\m\\b\\e\\r', 'dec' => 'Dez', 'december' => 'Dezember', + 'Feb' => '\\F\\e\\b\\r\\u\\a\\r', 'feb' => 'Feb', 'february' => 'Februar', 'format_date' => 'd\\. %s Y', 'format_date_hour' => 'd\\. %s Y \\u\\m H\\:i', 'fri' => 'Fr', + 'Jan' => '\\J\\a\\n\\u\\a\\r', 'jan' => 'Jan', 'january' => 'Januar', + 'Jul' => '\\J\\u\\l\\i', 'jul' => 'Jul', 'july' => 'Juli', + 'Jun' => '\\J\\u\\n\\i', 'jun' => 'Jun', 'june' => 'Juni', 'last_3_month' => 'Letzte drei Monate', @@ -78,17 +73,22 @@ return array( 'last_month' => 'Letzter Monat', 'last_week' => 'Letzte Woche', 'last_year' => 'Letztes Jahr', + 'Mar' => '\\M\\ä\\r\\z', 'mar' => 'Mär', 'march' => 'März', + 'May' => '\\M\\a\\i', 'may' => 'Mai', 'may_' => 'Mai', 'mon' => 'Mo', 'month' => 'Monat(en)', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r', 'nov' => 'Nov', 'november' => 'November', + 'Oct' => '\\O\\k\\t\\o\\b\\e\\r', 'oct' => 'Okt', 'october' => 'Oktober', 'sat' => 'Sa', + 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', 'sep' => 'Sep', 'september' => 'September', 'sun' => 'So', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -171,6 +172,7 @@ return array( 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Drucken', 'shaarli' => 'Shaarli', diff --git a/app/i18n/de/index.php b/app/i18n/de/index.php index 2d0dcc2dd..10172e6f5 100644 --- a/app/i18n/de/index.php +++ b/app/i18n/de/index.php @@ -53,11 +53,11 @@ return array( 'starred' => 'Nur Favoriten zeigen', 'stats' => 'Statistiken', 'subscription' => 'Abonnementverwaltung', - 'tags' => 'My labels', //TODO + 'tags' => 'My labels', //TODO - Translation 'unread' => 'Nur ungelesene zeigen', ), 'share' => 'Teilen', 'tag' => array( - 'related' => 'Verwandte Tags', //TODO + 'related' => 'Verwandte Tags', ), ); diff --git a/app/i18n/de/install.php b/app/i18n/de/install.php index d5a28f440..6fc8f2149 100644 --- a/app/i18n/de/install.php +++ b/app/i18n/de/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'Datenbank-Konfiguration ist gespeichert worden.', ), 'host' => 'Host', - 'prefix' => 'Tabellen-Präfix', 'password' => 'SQL-Password', + 'prefix' => 'Tabellen-Präfix', 'type' => 'Datenbank-Typ', 'username' => 'SQL-Nutzername', ), diff --git a/app/i18n/de/sub.php b/app/i18n/de/sub.php index 6a1100dba..aa408e8c7 100644 --- a/app/i18n/de/sub.php +++ b/app/i18n/de/sub.php @@ -45,6 +45,14 @@ return array( 'main_stream' => 'In Haupt-Feeds zeigen', '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', 'stats' => 'Statistiken', 'think_to_add' => 'Sie können Feeds hinzufügen.', @@ -55,7 +63,6 @@ return array( 'url' => 'Feed-URL', 'validator' => 'Überprüfen Sie die Gültigkeit des Feeds', 'website' => 'Webseiten-URL', - 'pubsubhubbub' => 'Sofortbenachrichtigung mit PubSubHubbub', ), '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.', diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php index 9db14978f..004089ffc 100644 --- a/app/i18n/en/admin.php +++ b/app/i18n/en/admin.php @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Author', + 'community' => 'Available community extensions', + 'description' => 'Description', 'disabled' => 'Disabled', 'empty_list' => 'There are no installed extensions', 'enabled' => 'Enabled', + 'latest' => 'Installed', + 'name' => 'Name', 'no_configure_view' => 'This extension cannot be configured.', 'system' => array( '_' => 'System extensions', 'no_rights' => 'System extension (you have no rights on it)', ), 'title' => 'Extensions', + 'update' => 'Update available', 'user' => 'User extensions', - 'community' => 'Available community extensions', - 'name' => 'Name', 'version' => 'Version', - 'description' => 'Description', - 'author' => 'Author', - 'latest' => 'Installed', - 'update' => 'Update available', ), 'stats' => array( '_' => 'Statistics', @@ -162,6 +162,10 @@ return array( 'instance-name' => 'Instance name', 'max-categories' => 'Categories per user limit', 'max-feeds' => 'Feeds per user limit', + 'cookie-duration' => array( + 'help' => 'in seconds', + 'number' => 'Duration to keep logged in', + ), 'registration' => array( 'help' => '0 means that there is no account limit', 'number' => 'Max number of accounts', diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php index 5c128f8e7..c6471426f 100644 --- a/app/i18n/en/conf.php +++ b/app/i18n/en/conf.php @@ -28,6 +28,7 @@ return array( 'seconds' => 'seconds (0 means no timeout)', 'timeout' => 'HTML5 notification timeout', ), + 'show_nav_buttons' => 'Show the navigation buttons', 'theme' => 'Theme', 'title' => 'Display', 'width' => array( @@ -37,7 +38,17 @@ return array( 'no_limit' => 'No limit', '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( '_' => 'User queries', @@ -73,31 +84,19 @@ return array( 'state_15' => 'Display all articles', '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', 'after_onread' => 'After “mark all as read”,', 'articles_per_page' => 'Number of articles per page', 'auto_load_more' => 'Load more 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 articles (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', '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.', 'read' => array( 'article_open_on_website' => 'when article is opened on its original website', @@ -112,6 +111,7 @@ return array( 'all_articles' => 'Show all articles', 'unread' => 'Show only unread', ), + 'sides_close_article' => 'Clicking outside of article text area closes the article', 'sort' => array( '_' => 'Sort order', '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.', 'close_dropdown' => 'Close menus', 'collapse_article' => 'Collapse', - 'first_article' => 'Skip to the first article', + 'first_article' => 'Open the first article', 'focus_search' => 'Access search box', 'global_view' => 'Switch to global view', 'help' => 'Display documentation', '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', - 'mark_read' => 'Mark as read', 'mark_favorite' => 'Mark as favourite', + 'mark_read' => 'Mark as read', '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', + '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', 'other_action' => 'Other actions', - 'previous_article' => 'Skip to the previous article', + 'previous_article' => 'Open the previous article', 'reading_view' => 'Switch to reading view', 'rss_view' => 'Open RSS view in a new tab', 'see_on_website' => 'See on original website', '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', '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.', diff --git a/app/i18n/en/feedback.php b/app/i18n/en/feedback.php index 634b547f7..2322a62cc 100644 --- a/app/i18n/en/feedback.php +++ b/app/i18n/en/feedback.php @@ -50,6 +50,10 @@ return array( 'no_zip_extension' => 'ZIP extension is not present on your server.', 'zip_error' => 'An error occured during ZIP import.', ), + 'profile' => array( + 'error' => 'Your profile cannot be modified', + 'updated' => 'Your profile has been modified', + ), 'sub' => array( 'actualize' => 'Updating', 'articles' => array( @@ -109,8 +113,4 @@ return array( 'error' => 'User %s has not been updated', ), ), - 'profile' => array( - 'error' => 'Your profile cannot be modified', - 'updated' => 'Your profile has been modified', - ), ); diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php index 9f7da55a5..32f5ee02e 100644 --- a/app/i18n/en/gen.php +++ b/app/i18n/en/gen.php @@ -44,33 +44,28 @@ return 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' => 'April', + 'Aug' => '\\A\\u\\g\\u\\s\\t', 'aug' => 'Aug.', 'august' => 'August', 'before_yesterday' => 'Before yesterday', + 'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r', 'dec' => 'Dec.', 'december' => 'December', + 'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y', 'feb' => 'Feb.', 'february' => 'February', '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' => '\\J\\a\\n\\u\\a\\r\\y', 'jan' => 'Jan.', 'january' => 'January', + 'Jul' => '\\J\\u\\l\\y', 'jul' => 'July', 'july' => 'July', + 'Jun' => '\\J\\u\\n\\e', 'jun' => 'June', 'june' => 'June', 'last_3_month' => 'Last three months', @@ -78,16 +73,21 @@ return array( 'last_month' => 'Last month', 'last_week' => 'Last week', 'last_year' => 'Last year', + 'Mar' => '\\M\\a\\r\\c\\h', 'mar' => 'Mar.', 'march' => 'March', + 'May' => '\\M\\a\\y', 'may' => 'May', 'may_' => 'May', 'mon' => 'Mon', 'month' => 'months', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r', 'nov' => 'Nov.', 'november' => 'November', + 'Oct' => '\\O\\c\\t\\o\\b\\e\\r', 'oct' => 'Oct.', 'october' => 'October', + 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', 'sat' => 'Sat', 'sep' => 'Sept.', 'september' => 'September', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -171,6 +172,7 @@ return array( 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Print', 'shaarli' => 'Shaarli', diff --git a/app/i18n/en/index.php b/app/i18n/en/index.php index 427a769a0..46c415816 100644 --- a/app/i18n/en/index.php +++ b/app/i18n/en/index.php @@ -58,6 +58,6 @@ return array( ), 'share' => 'Share', 'tag' => array( - 'related' => 'Article tags', //TODO + 'related' => 'Article tags', ), ); diff --git a/app/i18n/en/install.php b/app/i18n/en/install.php index 53d2f9be0..395919e9a 100644 --- a/app/i18n/en/install.php +++ b/app/i18n/en/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'Database configuration has been saved.', ), 'host' => 'Host', - 'prefix' => 'Table prefix', 'password' => 'Database password', + 'prefix' => 'Table prefix', 'type' => 'Type of database', 'username' => 'Database username', ), @@ -69,8 +69,8 @@ return array( 'ok' => 'You have a recommended library to parse JSON.', ), '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( 'nok' => 'Cannot find the Minz framework.', diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php index 22c7edc30..9acbcbf33 100644 --- a/app/i18n/en/sub.php +++ b/app/i18n/en/sub.php @@ -45,6 +45,14 @@ return array( 'main_stream' => 'Show in main stream', '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', 'stats' => 'Statistics', 'think_to_add' => 'You may add some feeds.', @@ -55,7 +63,6 @@ return array( 'url' => 'Feed URL', 'validator' => 'Check the validity of the feed', 'website' => 'Website URL', - 'pubsubhubbub' => 'Instant notification with 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.', diff --git a/app/i18n/es/admin.php b/app/i18n/es/admin.php index db41057bf..0ec8549bd 100755 --- a/app/i18n/es/admin.php +++ b/app/i18n/es/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => 'Dispones de la extensión JSON.', ), '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( 'nok' => 'No se ha podido localizar el entorno Minz.', @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Author', //TODO - Translation + 'community' => 'Available community extensions', //TODO - Translation + 'description' => 'Description', //TODO - Translation 'disabled' => 'Desactivado', 'empty_list' => 'No hay extensiones instaladas', 'enabled' => 'Activado', + 'latest' => 'Installed', //TODO - Translation + 'name' => 'Name', //TODO - Translation 'no_configure_view' => 'Esta extensión no puede ser configurada.', 'system' => array( '_' => 'Sistema de extensiones', 'no_rights' => 'Sistema de extensiones (careces de los permisos necesarios)', ), 'title' => 'Extensiones', + 'update' => 'Update available', //TODO - Translation '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( '_' => 'Estadísticas', @@ -162,6 +162,10 @@ return array( 'instance-name' => 'Nombre de la fuente', 'max-categories' => 'Límite de categorías 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( 'help' => '0 significa que no hay límite en la cuenta', 'number' => 'Número máximo de cuentas', @@ -179,15 +183,15 @@ return array( 'user' => array( 'articles_and_size' => '%s articles (%s)', 'create' => 'Crear nuevo usuario', - 'delete_users' => 'Delete user', // TODO + 'delete_users' => 'Delete user', //TODO - Translation 'language' => 'Idioma', 'number' => 'Hay %d cuenta creada', 'numbers' => 'Hay %d cuentas creadas', 'password_form' => 'Contraseña<br /><small>(para el método de identificación por formulario web)</small>', 'password_format' => 'Mínimo de 7 caracteres', - 'selected' => 'Selected user', // TODO + 'selected' => 'Selected user', //TODO - Translation 'title' => 'Administrar usuarios', - 'update_users' => 'Update user', // TODO + 'update_users' => 'Update user', //TODO - Translation 'user_list' => 'Lista de usuarios', 'username' => 'Nombre de usuario', 'users' => 'Usuarios', diff --git a/app/i18n/es/conf.php b/app/i18n/es/conf.php index 095015d47..b7d87f375 100755 --- a/app/i18n/es/conf.php +++ b/app/i18n/es/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => 'Línea inferior', 'entry' => 'Iconos de artículos', 'publication_date' => 'Fecha de publicación', - 'related_tags' => 'Etiquetas relacionadas', //TODO + 'related_tags' => 'Etiquetas relacionadas', 'sharing' => 'Compartir', 'top_line' => 'Línea superior', ), @@ -28,6 +28,7 @@ return array( 'seconds' => 'segundos (0 significa sin límite de espera)', 'timeout' => 'Notificación de fin de espera HTML5', ), + 'show_nav_buttons' => 'Show the navigation buttons', //TODO - Translation 'theme' => 'Tema', 'title' => 'Visualización', 'width' => array( @@ -37,12 +38,22 @@ return array( 'no_limit' => 'Sin límite', '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( '_' => 'Consultas de usuario', '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:', 'get_all' => 'Mostrar todos los artículos', 'get_category' => 'Mostrar la categoría "%s"', @@ -53,7 +64,7 @@ return array( 'number' => 'Consulta n° %d', 'order_asc' => 'Mostrar primero los artículos más antiguos', 'order_desc' => 'Mostrar primero los artículos más recientes', - 'remove' => 'Remove user query', // TODO + 'remove' => 'Remove user query', //TODO - Translation 'search' => 'Buscar "%s"', 'state_0' => 'Mostrar todos los artículos', 'state_1' => 'Mostrar artículos leídos', @@ -73,31 +84,19 @@ return array( 'state_15' => 'Mostrar todos los artículos', '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( '_' => 'Lectura', 'after_onread' => 'Tras “marcar todo como leído”,', '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_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”', 'display_articles_unfolded' => 'Mostrar los artículos sin expandir 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")', '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)', + 'mark_updated_article_unread' => 'Marcar artículos actualizados como no leídos', 'number_divided_when_reader' => 'Dividido en 2 en la vista de lectura.', 'read' => array( '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', 'unread' => 'Mostrar solo pendientes', ), + 'sides_close_article' => 'Pinchar fuera del área de texto del artículo lo cerrará', 'sort' => array( '_' => 'Orden', 'newer_first' => 'Nuevos primero', @@ -128,7 +128,7 @@ return array( ), 'sharing' => array( '_' => 'Compartir', - 'add' => 'Add a sharing method', // TODO + 'add' => 'Add a sharing method', //TODO - Translation 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -136,7 +136,7 @@ return array( 'g+' => 'Google+', 'more_information' => 'Más información', 'print' => 'Print', - 'remove' => 'Remove sharing method', // TODO + 'remove' => 'Remove sharing method', //TODO - Translation 'shaarli' => 'Shaarli', 'share_name' => 'Compartir nombre a mostrar', 'share_url' => 'Compatir URL a usar', @@ -153,27 +153,30 @@ return array( 'collapse_article' => 'Contraer', 'first_article' => 'Saltar al primer artículo', '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', 'javascript' => 'JavaScript debe estar activado para poder usar atajos de teclado', 'last_article' => 'Saltar al último artículo', 'load_more' => 'Cargar más artículos', - 'mark_read' => 'Marcar como leído', 'mark_favorite' => 'Marcar como favorito', + 'mark_read' => 'Marcar como leído', '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_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation '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', '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', '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', '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.', - 'views' => 'Views', // TODO + 'views' => 'Views', //TODO - Translation ), 'user' => array( 'articles_and_size' => '%s artículos (%s)', diff --git a/app/i18n/es/feedback.php b/app/i18n/es/feedback.php index 38548e901..d70ccfe8a 100755 --- a/app/i18n/es/feedback.php +++ b/app/i18n/es/feedback.php @@ -50,11 +50,15 @@ return array( 'no_zip_extension' => 'La extensión ZIP no está disponible en tu servidor.', '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( 'actualize' => 'Actualización', '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( 'created' => 'Se ha creado la categoría %s.', @@ -76,7 +80,7 @@ return array( 'already_subscribed' => 'Ya estás suscrito a <em>%s</em>', 'deleted' => 'Fuente eliminada', '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', 'n_actualized' => 'Se han actualiado %d fuentes', 'n_entries_deleted' => 'Se han eliminado %d artículos', @@ -105,12 +109,8 @@ return array( 'error' => 'El usuario %s no ha podido ser eliminado', ), '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', - ), ); diff --git a/app/i18n/es/gen.php b/app/i18n/es/gen.php index fe3d62e2d..db36e5f5b 100755 --- a/app/i18n/es/gen.php +++ b/app/i18n/es/gen.php @@ -19,7 +19,7 @@ return array( 'see_website' => 'Ver web', 'submit' => 'Enviar', 'truncate' => 'Borrar todos los artículos', - 'update' => 'Update', // TODO + 'update' => 'Update', //TODO - Translation ), 'auth' => array( 'email' => 'Correo electrónico', @@ -44,33 +44,28 @@ return array( ), 'date' => array( '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', 'april' => 'abril', + 'Aug' => '\\A\\g\\o\\s\\t\\o', 'aug' => 'ago', 'august' => 'agosto', 'before_yesterday' => 'Anteayer', + 'Dec' => '\\D\\i\\c\\i\\e\\m\\b\\r\\e', 'dec' => 'dic', 'december' => 'diciembre', + 'Feb' => '\\F\\e\\b\\r\\e\\r\\o', 'feb' => 'feb', 'february' => 'febrero', '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' => 'Vie', + 'Jan' => '\\E\\n\\e\\r\\o', 'jan' => 'ene', 'january' => 'ene', + 'Jul' => '\\J\\u\\l\\i\\o', 'jul' => 'jul', 'july' => 'julio', + 'Jun' => '\\J\\u\\n\\i\\o', 'jun' => 'jun', 'june' => 'junio', 'last_3_month' => 'Últimos tres meses', @@ -78,17 +73,22 @@ return array( 'last_month' => 'Mes pasado', 'last_week' => 'Semana pasada', 'last_year' => 'Año pasado', + 'Mar' => '\\M\\a\\r\\z\\o', 'mar' => 'mar', 'march' => 'marzo', + 'May' => '\\M\\a\\y\\o', 'may' => 'mayo', 'may_' => 'may', 'mon' => 'Lun', 'month' => 'meses', + 'Nov' => '\\N\\o\\v\\i\\e\\m\\b\\r\\e', 'nov' => 'nov', 'november' => 'noviembre', + 'Oct' => '\\O\\c\\t\\u\\b\\r\\e', 'oct' => 'oct', 'october' => 'octubre', 'sat' => 'Sab', + 'Sep' => '\\S\\e\\p\\t\\i\\e\\m\\b\\r\\e', 'sep' => 'sep', 'september' => 'septiembre', 'sun' => 'Dom', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -160,7 +161,6 @@ return array( 'previous' => 'Anterior', ), 'share' => array( - 'Known' => 'Known based sites', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Known based sites', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Print', 'shaarli' => 'Shaarli', diff --git a/app/i18n/es/index.php b/app/i18n/es/index.php index 1ed6066fb..d7a42537b 100755 --- a/app/i18n/es/index.php +++ b/app/i18n/es/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => 'Marcar todo como leído', 'mark_cat_read' => 'Marcar categoría 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', 'non-starred' => 'Mostrar todos menos los favoritos', 'normal_view' => 'Vista normal', @@ -53,11 +53,11 @@ return array( 'starred' => 'Mostrar solo los favoritos', 'stats' => 'Estadísticas', 'subscription' => 'Administración de suscripciones', - 'tags' => 'My labels', //TODO + 'tags' => 'My labels', //TODO - Translation 'unread' => 'Mostar solo no leídos', ), 'share' => 'Compartir', 'tag' => array( - 'related' => 'Etiquetas relacionadas', //TODO + 'related' => 'Etiquetas relacionadas', //TODO - Translation ), ); diff --git a/app/i18n/es/install.php b/app/i18n/es/install.php index a9be807c7..44236ccae 100755 --- a/app/i18n/es/install.php +++ b/app/i18n/es/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'La configuración de la base de datos ha sido guardada.', ), 'host' => 'Servidor', - 'prefix' => 'Prefijo de la tabla', 'password' => 'Contraseña de la base de datos', + 'prefix' => 'Prefijo de la tabla', 'type' => 'Tipo de 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.', ), '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( 'nok' => 'No se ha podido localizar el entorno Minz.', diff --git a/app/i18n/es/sub.php b/app/i18n/es/sub.php index 8a4fb98de..64e420dc1 100755 --- a/app/i18n/es/sub.php +++ b/app/i18n/es/sub.php @@ -2,8 +2,13 @@ return 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( '_' => 'Categoría', @@ -22,7 +27,7 @@ return array( 'password' => 'Contraseña 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_path' => 'Ruta a la CSS de los artículos en la web original', 'description' => 'Descripción', @@ -31,26 +36,37 @@ return array( 'informations' => 'Información', '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>.', - 'mute' => 'mute', // TODO + 'mute' => 'mute', //TODO - Translation 'no_selected' => 'No hay funentes seleccionadas.', 'number_entries' => '%d artículos', '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', - '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', 'think_to_add' => 'Puedes añadir fuentes.', - 'timeout' => 'Timeout in seconds', //TODO + 'timeout' => 'Timeout in seconds', //TODO - Translation 'title' => 'Título', 'title_add' => 'Añadir fuente RSS', 'ttl' => 'No actualizar de forma automática con una frecuencia mayor a', 'url' => 'URL de la fuente', 'validator' => 'Verifica la validez de la fuente', '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( 'export' => 'Exportar', @@ -67,9 +83,11 @@ return array( 'bookmark' => 'Suscribirse (favorito FreshRSS)', 'import_export' => 'Importar / exportar', 'subscription_management' => 'Administración de suscripciones', + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), 'title' => array( '_' => 'Administración de suscripciones', 'feed_management' => 'Administración de fuentes RSS', + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), ); diff --git a/app/i18n/fr/admin.php b/app/i18n/fr/admin.php index 1874f2c77..74605b5ee 100644 --- a/app/i18n/fr/admin.php +++ b/app/i18n/fr/admin.php @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Auteur', + 'community' => 'Extensions utilisateur disponibles', + 'description' => 'Description', 'disabled' => 'Désactivée', 'empty_list' => 'Aucune extension installée', 'enabled' => 'Activée', + 'latest' => 'Installée', + 'name' => 'Nom', 'no_configure_view' => 'Cette extension n’a pas à être configurée', 'system' => array( '_' => 'Extensions système', 'no_rights' => 'Extensions système (contrôlées par l’administrateur)', ), 'title' => 'Extensions', + 'update' => 'Mise à jour disponible', 'user' => 'Extensions utilisateur', - 'community' => 'Extensions utilisateur disponibles', - 'name' => 'Nom', 'version' => 'Version', - 'description' => 'Description', - 'author' => 'Auteur', - 'latest' => 'Installée', - 'update' => 'Mise à jour disponible', ), 'stats' => array( '_' => 'Statistiques', @@ -162,6 +162,10 @@ return array( 'instance-name' => 'Nom de l’instance', 'max-categories' => 'Limite de catégories 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( 'help' => 'Un chiffre de 0 signifie que l’on peut créer un nombre infini de comptes', 'number' => 'Nombre max de comptes', diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php index 01239770b..5c8e91c89 100644 --- a/app/i18n/fr/conf.php +++ b/app/i18n/fr/conf.php @@ -28,6 +28,7 @@ return array( 'seconds' => 'secondes (0 signifie aucun timeout)', 'timeout' => 'Temps d’affichage de la notification HTML5', ), + 'show_nav_buttons' => 'Afficher les boutons de navigation', 'theme' => 'Thème', 'title' => 'Affichage', 'width' => array( @@ -37,7 +38,17 @@ return array( 'no_limit' => 'Pas de limite', '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( '_' => 'Filtres utilisateurs', @@ -73,31 +84,19 @@ return array( 'state_15' => 'Afficher tous les articles', '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( '_' => 'Lecture', 'after_onread' => 'Après “marquer tout comme lu”,', 'articles_per_page' => 'Nombre d’articles par page', 'auto_load_more' => 'Charger les articles suivants en bas de page', '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”', 'display_articles_unfolded' => 'Afficher les articles dépliés 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”)', '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)', + 'mark_updated_article_unread' => 'Marquer les articles mis à jour comme non-lus', 'number_divided_when_reader' => 'Divisé par 2 dans la vue de lecture.', 'read' => array( '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', 'unread' => 'Afficher les non lus', ), + 'sides_close_article' => 'Cliquer hors de la zone de texte ferme l’article', 'sort' => array( '_' => 'Ordre de tri', 'newer_first' => 'Plus récents en premier', @@ -158,10 +158,11 @@ return array( 'javascript' => 'Le JavaScript doit être activé pour pouvoir profiter des raccourcis.', 'last_article' => 'Passer au dernier article', 'load_more' => 'Charger plus d’articles', - 'mark_read' => 'Marquer comme lu', 'mark_favorite' => 'Mettre en favori', + 'mark_read' => 'Marquer comme lu', '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_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation 'next_article' => 'Passer à l’article suivant', 'normal_view' => 'Basculer vers la vue normale', 'other_action' => 'Autres actions', @@ -170,6 +171,8 @@ return array( 'rss_view' => 'Ouvrir le flux RSS dans un nouvel onglet', 'see_on_website' => 'Voir sur le site d’origine', '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', '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.', diff --git a/app/i18n/fr/feedback.php b/app/i18n/fr/feedback.php index dafdd353d..328113c25 100644 --- a/app/i18n/fr/feedback.php +++ b/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.', '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( 'actualize' => 'Actualiser', 'articles' => array( @@ -109,8 +113,4 @@ return array( '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', - ), ); diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php index 1e1cef590..86d8461e6 100644 --- a/app/i18n/fr/gen.php +++ b/app/i18n/fr/gen.php @@ -44,33 +44,28 @@ return array( ), 'date' => array( '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.', 'april' => 'avril', + 'Aug' => '\\a\\o\\û\\t', 'aug' => 'août', 'august' => 'août', 'before_yesterday' => 'À partir d’avant-hier', + 'Dec' => '\\d\\é\\c\\e\\m\\b\\r\\e', 'dec' => 'déc.', 'december' => 'décembre', + 'Feb' => '\\f\\é\\v\\r\\i\\e\\r', 'feb' => 'fév.', 'february' => 'février', 'format_date' => 'j %s Y', 'format_date_hour' => 'j %s Y \\à H\\:i', 'fri' => 'ven.', + 'Jan' => '\\j\\a\\n\\v\\i\\e\\r', 'jan' => 'jan.', 'january' => 'janvier', + 'Jul' => '\\j\\u\\i\\l\\l\\e\\t', 'jul' => 'jui.', 'july' => 'juillet', + 'Jun' => '\\j\\u\\i\\n', 'jun' => 'juin', 'june' => 'juin', 'last_3_month' => 'Depuis les trois derniers mois', @@ -78,17 +73,22 @@ return array( 'last_month' => 'Depuis le mois dernier', 'last_week' => 'Depuis la semaine dernière', 'last_year' => 'Depuis l’année dernière', + 'Mar' => '\\m\\a\\r\\s', 'mar' => 'mars', 'march' => 'mars', + 'May' => '\\m\\a\\i', 'may' => 'mai', 'may_' => 'mai', 'mon' => 'lun.', 'month' => 'mois', + 'Nov' => '\\n\\o\\v\\e\\m\\b\\r\\e', 'nov' => 'nov.', 'november' => 'novembre', + 'Oct' => '\\o\\c\\t\\o\\b\\r\\e', 'oct' => 'oct.', 'october' => 'octobre', 'sat' => 'sam.', + 'Sep' => '\\s\\e\\p\\t\\e\\m\\b\\r\\e', 'sep' => 'sep.', 'september' => 'septembre', 'sun' => 'dim.', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -160,7 +161,6 @@ return array( 'previous' => 'Précédent', ), 'share' => array( - 'Known' => 'Sites basés sur Known', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Courriel', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Sites basés sur Known', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Imprimer', 'shaarli' => 'Shaarli', diff --git a/app/i18n/fr/sub.php b/app/i18n/fr/sub.php index d3921f1d9..6cb31414d 100644 --- a/app/i18n/fr/sub.php +++ b/app/i18n/fr/sub.php @@ -45,6 +45,14 @@ return array( 'main_stream' => 'Afficher dans le flux principal', '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', 'stats' => 'Statistiques', 'think_to_add' => 'Vous pouvez ajouter des flux.', @@ -55,7 +63,6 @@ return array( 'url' => 'URL du flux', 'validator' => 'Vérifier la validité du flux', 'website' => 'URL du site', - 'pubsubhubbub' => 'Notification instantanée par PubSubHubbub', ), '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.', diff --git a/app/i18n/he/admin.php b/app/i18n/he/admin.php index 71f86357e..e0dfc405d 100644 --- a/app/i18n/he/admin.php +++ b/app/i18n/he/admin.php @@ -8,10 +8,10 @@ return array( 'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)', 'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)', 'none' => 'ללא (מסוכן)', - 'title' => 'Authentication', // @todo + 'title' => 'Authentication', //TODO - Translation 'title_reset' => 'איפוס אימות', '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' => 'שיטת אימות', 'unsafe_autologin' => 'הרשאה להתחברות אוטומטית בפורמט: ', ), @@ -21,12 +21,12 @@ return array( 'ok' => 'ההרשאות בתיקיית המטמון תקינות', ), '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( - '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( 'nok' => 'הספרייה הנדרשת ל character type checking (php-ctype) אינה מותקנת', @@ -34,44 +34,44 @@ return array( ), 'curl' => array( 'nok' => 'בURL לא מותקן (php-curl package)', - 'ok' => 'You have cURL extension.', // @todo + 'ok' => 'You have cURL extension.', //TODO - Translation ), 'data' => array( 'nok' => 'יש לבדוק את ההרשאות בתיקייה <em>%s</em>. שרת הHTTP חייב להיות בעל הרשאות כתיבה.', 'ok' => 'ההרשאות בתיקיית הדאטא תקינות', ), - 'database' => 'Database installation', // @todo + 'database' => 'Database installation', //TODO - Translation 'dom' => array( 'nok' => 'הספרייה הנדרשת לסיור ב DOM אינה מותקנת (php-xml package)', 'ok' => 'הספרייה הנדרשת לסיור ב DOM מותקנת', ), '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( - '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 תקינות', ), '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( - '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( - '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( - '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( - 'nok' => 'You lack the Minz framework.', // @todo + 'nok' => 'You lack the Minz framework.', //TODO - Translation 'ok' => 'יש לכם את תשתית Minz', ), 'pcre' => array( @@ -83,46 +83,46 @@ return array( 'ok' => 'PDO מותקן ולפחות אחד ממנהלי ההתקן הנתמכים מותקן (pdo_mysql, pdo_sqlite)', ), 'php' => array( - '_' => 'PHP installation', // @todo + '_' => 'PHP installation', //TODO - Translation 'nok' => 'גירסת PHP שלכם היא %s אך FreshRSS דורש לפחות את גירסה %s', 'ok' => 'גירסת PHP שלכם היא %s, שתואמת ל FreshRSS', ), '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( - '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( - '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( - '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( - '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 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( '_' => 'סטטיסטיקות', @@ -131,9 +131,9 @@ return array( 'entry_count' => 'סכום המאמרים', 'entry_per_category' => 'מאמרים על פי קטגוריה', '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' => 'חלוקת המאמרים', 'feed' => 'הזנה', 'feed_per_category' => 'הזנות על פי קטגוריה', @@ -157,37 +157,41 @@ return array( 'top_feed' => 'עשרת ההזנות המובילות', ), '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( - '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( '_' => 'מערכת העדכון', 'apply' => 'החלת העדכון', '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', 'none' => 'אין עדכון להחלה', 'title' => 'מערכת העדכון', ), 'user' => array( - 'articles_and_size' => '%s articles (%s)', // @todo + 'articles_and_size' => '%s articles (%s)', //TODO - Translation 'create' => 'יצירת משתמש חדש', - 'delete_users' => 'Delete user', // TODO + 'delete_users' => 'Delete user', //TODO - Translation '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_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' => 'רשימת משתמשים', 'username' => 'שם משתמש', 'users' => 'משתמשים', diff --git a/app/i18n/he/conf.php b/app/i18n/he/conf.php index 2ab8aefa9..2f699bcf2 100644 --- a/app/i18n/he/conf.php +++ b/app/i18n/he/conf.php @@ -6,7 +6,7 @@ return array( 'advanced' => 'מתקדם', 'delete_after' => 'מחיקת מאמרים לאחר', '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_help' => 'ביצוע לעיתים קרובות על מנת למטב את בסיס הנתונים', 'purge_now' => 'ניקוי עכשיו', @@ -19,7 +19,7 @@ return array( 'bottom_line' => 'שורה תחתונה', 'entry' => 'סמלילי מאמרים', 'publication_date' => 'תאריך הפרסום', - 'related_tags' => 'תגיות קשורות', //TODO + 'related_tags' => 'תגיות קשורות', //TODO - Translation 'sharing' => 'שיתוף', 'top_line' => 'שורה עליונה', ), @@ -28,6 +28,7 @@ return array( 'seconds' => 'שניות (0 משמעותה ללא פג תוקף)', 'timeout' => 'HTML5 התראה פג תוקף', ), + 'show_nav_buttons' => 'Show the navigation buttons', //TODO - Translation 'theme' => 'ערכת נושא', 'title' => 'תצוגה', 'width' => array( @@ -37,12 +38,22 @@ return array( 'no_limit' => 'ללא הגבלה', '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( '_' => 'שאילתות', 'deprecated' => 'שאילתה זו אינה בתוקף יותר, הפיד או הקטגוריה לייחוס נמחקו.', - 'display' => 'Display user query results', // TODO + 'display' => 'Display user query results', //TODO - Translation 'filter' => 'מסננים בשימוש:', 'get_all' => 'הצגת כל המאמרים', 'get_category' => 'הצגת קטגוריה "%s"', @@ -53,7 +64,7 @@ return array( 'number' => 'שאילתה מספר °%d', 'order_asc' => 'הצגת מאמרים ישנים בראש', 'order_desc' => 'הצגת מאמרים חדשים בראש', - 'remove' => 'Remove user query', // TODO + 'remove' => 'Remove user query', //TODO - Translation 'search' => 'חיפוש "%s"', 'state_0' => 'הצגת כל המאמרים', 'state_1' => 'הצגת מאמרים שנקראו', @@ -73,28 +84,19 @@ return array( 'state_15' => 'הצגת כל המאמרים', '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( '_' => 'קריאה', 'after_onread' => 'לאחר “סימון הכל כנקרא”,', 'articles_per_page' => 'מספר המאמרים בעמוד', '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' => 'הצגת דו-שיח לאישור “סימון הכל כנקרא” ', 'display_articles_unfolded' => 'הצגת מאמרים בשלמותם כברירת מחדל', 'display_categories_unfolded' => 'הצגת קטגוריות מקופלות כברירת מחדל', 'hide_read_feeds' => 'הסתרת קטגוריות & הזנות ללא מאמרים שלא נקראו (לא עובד יחד עם “הצגת כל המאמרים”)', 'img_with_lazyload' => 'שימוש ב "טעינה עצלה" על מנת לטעון תמונות', - 'sides_close_article' => 'Clicking outside of article text area closes the article', // @todo 'jump_next' => 'קפיצה לפריט הבא שלא נקרא (הזנה או קטגוריה)', + 'mark_updated_article_unread' => 'Mark updated articles as unread', //TODO - Translation 'number_divided_when_reader' => 'חלוקה ב2 במצב קריאה.', 'read' => array( 'article_open_on_website' => 'כאשר מאמר נפתח באתר המקורי', @@ -109,6 +111,7 @@ return array( 'all_articles' => 'הצגת כל המאמרים', 'unread' => 'הצגת מאמרים שלא נקראו בלבד', ), + 'sides_close_article' => 'Clicking outside of article text area closes the article', //TODO - Translation 'sort' => array( '_' => 'סדר המיון', 'newer_first' => 'חדשים בראש', @@ -125,7 +128,7 @@ return array( ), 'sharing' => array( '_' => 'שיתוף', - 'add' => 'Add a sharing method', // TODO + 'add' => 'Add a sharing method', //TODO - Translation 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'דואר אלקטרוני', @@ -133,7 +136,7 @@ return array( 'g+' => 'Google+', 'more_information' => 'מידע נוסף', 'print' => 'הדפסה', - 'remove' => 'Remove sharing method', // TODO + 'remove' => 'Remove sharing method', //TODO - Translation 'shaarli' => 'Shaarli', 'share_name' => 'שיתוף שם לתצוגה', 'share_url' => 'לשימוש שתפו URL', @@ -146,34 +149,37 @@ return array( 'article_action' => 'פעולות על מאמרים', 'auto_share' => 'שיתוף', 'auto_share_help' => 'אם יש רק מצב שיתוף אחד, הוא מופעל. אחרת המצבים נבחרים על בסיס המספר שלהם.', - 'close_dropdown' => 'Close menus', // @todo + 'close_dropdown' => 'Close menus', //TODO - Translation 'collapse_article' => 'כיווץ', 'first_article' => 'דילוג למאמר הראשון', 'focus_search' => 'גישה לתיבת החיפוש', - 'global_view' => 'Switch to global view', // TODO + 'global_view' => 'Switch to global view', //TODO - Translation 'help' => 'הצגת התיעוד', 'javascript' => 'חובה להפעיל JavaScript על מנת לעשות שימוש בקיצורי דרך', 'last_article' => 'דילוג למאמר האחרון', 'load_more' => 'טעינת מאמרים נוספים', - 'mark_read' => 'סימון כנקרא', 'mark_favorite' => 'סימון כמועדף', + 'mark_read' => 'סימון כנקרא', 'navigation' => 'ניווט', 'navigation_help' => 'בעזרת מקש השיפט קיצורי דרך חלים על הזנות .<br/>עם מקש האלט הם חלים על קטגוריות.', + 'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation 'next_article' => 'דילוג למאמר הבא', - 'normal_view' => 'Switch to normal view', // TODO + 'normal_view' => 'Switch to normal view', //TODO - Translation 'other_action' => 'פעולות אחרות', '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' => 'ראו את המקור באתר', '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' => 'קיצורי דרך', 'user_filter' => 'גישה למססנים', 'user_filter_help' => 'אם יש רק מזנן אחד הוא יהיה בשימוש. אחרת המסננים ישמשו על בסיס המספר שלהם.', - 'views' => 'Views', // TODO + 'views' => 'Views', //TODO - Translation ), 'user' => array( - 'articles_and_size' => '%s articles (%s)', // @todo + 'articles_and_size' => '%s articles (%s)', //TODO - Translation 'current' => 'משתמש נוכחי', 'is_admin' => 'מנהל', 'users' => 'משתמשים', diff --git a/app/i18n/he/feedback.php b/app/i18n/he/feedback.php index 369714795..f972173cb 100644 --- a/app/i18n/he/feedback.php +++ b/app/i18n/he/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'You are disconnected', // @todo ), 'no_password_set' => 'לא הוגדרה סיסמת מנהל. תכונה זו אינה זמינה.', - 'not_persona' => 'ניתן לאפס את מערכת הפרסונה בלבד.', ), 'conf' => array( 'error' => 'An error occurred during configuration saving', // @todo @@ -51,24 +50,28 @@ return array( 'no_zip_extension' => 'הרחבת ZIP אינה מותקנת על השרת.', 'zip_error' => 'אירעה שגיאה במהלך ייבוא קובץ הZIP.', ), + 'profile' => array( + 'error' => 'Your profile cannot be modified', // @todo + 'updated' => 'Your profile has been modified', // @todo + ), 'sub' => array( 'actualize' => 'מימוש', '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( - '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' => 'הקטגוריה רוקנה', - '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( 'actualized' => '<em>%s</em> עודכן', @@ -76,20 +79,20 @@ return array( 'added' => 'RSS הזנת <em>%s</em> נוספה', 'already_subscribed' => 'אתה כבר רשום ל <em>%s</em>', '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> אינו תקין', 'n_actualized' => '%d הזנות עודכנו', 'n_entries_deleted' => '%d המאמרים נמחקו', 'no_refresh' => 'אין הזנה שניתן לרענן…', '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' => 'ההזנה התעדכנה', ), 'purge_completed' => 'הניקוי הושלם (%d מאמרים נמחקו)', ), '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', 'file_is_nok' => 'יש לבדוק את ההרשאות בתיקייה <em>%s</em>. שרת הHTTP חייב להיות בעל הרשאות כתיבה.', 'finished' => 'העדכון הושלם!', @@ -99,19 +102,15 @@ return array( 'user' => array( 'created' => array( '_' => 'המשתמש %s נוצר', - 'error' => 'User %s cannot be created', // @todo + 'error' => 'User %s cannot be created', //TODO - Translation ), 'deleted' => array( '_' => 'המשתמש %s נמחק', - 'error' => 'User %s cannot be deleted', // @todo + 'error' => 'User %s cannot be deleted', //TODO - Translation ), '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 - ), ); diff --git a/app/i18n/he/gen.php b/app/i18n/he/gen.php index 26b8f99e6..cf4a1fcda 100644 --- a/app/i18n/he/gen.php +++ b/app/i18n/he/gen.php @@ -6,23 +6,23 @@ return array( 'back_to_rss_feeds' => '← חזרה להזנות הRSS שלך', 'cancel' => 'ביטול', 'create' => 'יצירה', - 'disable' => 'Disable', // @todo - 'empty' => 'Empty', // @todo - 'enable' => 'Enable', // @todo + 'disable' => 'Disable', //TODO - Translation + 'empty' => 'Empty', //TODO - Translation + 'enable' => 'Enable', //TODO - Translation 'export' => 'ייצוא', 'filter' => 'מסנן', 'import' => 'ייבוא', 'manage' => 'ניהול', 'mark_read' => 'סימון כנקרא', 'mark_favorite' => 'סימון כמועדף', - 'remove' => 'Remove', // @todo + 'remove' => 'Remove', //TODO - Translation 'see_website' => 'ראו אתר', 'submit' => 'אישור', 'truncate' => 'מחיקת כל המאמרים', - 'update' => 'Update', // TODO + 'update' => 'Update', //TODO - Translation ), 'auth' => array( - 'email' => 'Email address', // @todo + 'email' => 'Email address', //TODO - Translation 'keep_logged_in' => 'השאר מחובר <small>חודש</small>', 'login' => 'כניסה לחשבון', 'logout' => 'יציאה מהחשבון', @@ -31,46 +31,41 @@ return array( 'format' => '<small>At least 7 characters</small>', ), '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' => 'איפוס אימות', 'username' => array( '_' => 'שם משתמש', 'admin' => 'שם משתמש של המנהל', - 'format' => '<small>maximum 16 alphanumeric characters</small>', // @todo + 'format' => '<small>maximum 16 alphanumeric characters</small>', //TODO - Translation ), ), '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' => '\\A\\u\\g\\u\\s\\t', 'aug' => 'aug', 'august' => 'Aug', 'before_yesterday' => 'ישן יותר', + 'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r', 'dec' => 'dec', 'december' => 'Dec', + 'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y', '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' => '\\J\\a\\n\\u\\a\\r\\y', 'jan' => 'jan', 'january' => 'Jan', + 'Jul' => '\\J\\u\\l\\y', 'jul' => 'jul', 'july' => 'Jul', + 'Jun' => '\\J\\u\\n\\e', 'jun' => 'jun', 'june' => 'Jun', 'last_3_month' => 'בשלושת החודשים האחרונים', @@ -78,17 +73,22 @@ return array( 'last_month' => 'בחודש שעבר', 'last_week' => 'בשבוע שעבר', 'last_year' => 'בשנה האחרונה', + 'Mar' => '\\M\\a\\r\\c\\h', 'mar' => 'mar', 'march' => 'Mar', + 'May' => '\\M\\a\\y', 'may' => 'May', 'may_' => 'May', 'mon' => 'Mon', 'month' => 'חודשים', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r', 'nov' => 'nov', 'november' => 'Nov', + 'Oct' => '\\O\\c\\t\\o\\b\\e\\r', 'oct' => 'oct', 'october' => 'Oct', 'sat' => 'Sat', + 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', 'sep' => 'sep', 'september' => 'Sep', 'sun' => 'Sun', @@ -103,12 +103,12 @@ return array( 'about' => 'אודות FreshRSS', ), 'js' => array( - 'category_empty' => 'Empty category', // @todo + 'category_empty' => 'Empty category', //TODO - Translation 'confirm_action' => 'האם אתם בטוחים שברצונכם לבצע פעולה זו? אין אפשרות לבטל אותה!', 'confirm_action_feed_cat' => 'האם אתם בטוחים שברצוניכם לבצע פעולה זו? מועדפים ושאילתות עשויות לאבוד. אין אפשרות לבטל אותה!', 'feedback' => array( '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: מאמרים חדשים!', ), 'new_article' => 'מאמרים חדשים זמינים, לחצו לרענון העמוד.', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -133,11 +134,11 @@ return array( 'about' => 'אודות', 'admin' => 'ניהול', 'archiving' => 'ארכוב', - 'authentication' => 'Authentication', // @todo - 'check_install' => 'Installation checking', // @todo + 'authentication' => 'Authentication', //TODO - Translation + 'check_install' => 'Installation checking', //TODO - Translation 'configuration' => 'הגדרות', 'display' => 'תצוגה', - 'extensions' => 'Extensions', // @todo + 'extensions' => 'Extensions', //TODO - Translation 'logs' => 'לוגים', 'queries' => 'שאילתות', 'reading' => 'קריאה', @@ -145,10 +146,10 @@ return array( 'sharing' => 'שיתוף', 'shortcuts' => 'קיצורי דרך', 'stats' => 'סטטיסטיקות', - 'system' => 'System configuration', // @todo + 'system' => 'System configuration', //TODO - Translation 'update' => 'עדכון', - 'user_management' => 'Manage users', // @todo - 'user_profile' => 'Profile', // @todo + 'user_management' => 'Manage users', //TODO - Translation + 'user_profile' => 'Profile', //TODO - Translation ), 'pagination' => array( 'first' => 'הראשון', @@ -171,6 +172,7 @@ return array( 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'הדפסה', 'shaarli' => 'Shaarli', @@ -186,7 +188,7 @@ return array( 'damn' => 'הו לא!', 'default_category' => 'ללא קטגוריה', 'no' => 'לא', - 'not_applicable' => 'Not available', // @todo + 'not_applicable' => 'Not available', //TODO - Translation 'ok' => 'כן!', 'or' => 'או', 'yes' => 'כן', diff --git a/app/i18n/he/index.php b/app/i18n/he/index.php index d33c09b08..e01a02773 100644 --- a/app/i18n/he/index.php +++ b/app/i18n/he/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => 'סימון הכל כנקרא', 'mark_cat_read' => 'סימון קטגוריה כנקראה', 'mark_feed_read' => 'סימון הזנה כנקראה', - 'mark_selection_unread' => 'Mark selection as unread', //TODO + 'mark_selection_unread' => 'Mark selection as unread', //TODO - Translation 'newer_first' => 'חדשים בראש', 'non-starred' => 'הצגת הכל פרט למועדפים', 'normal_view' => 'תצוגה רגילה', @@ -53,11 +53,11 @@ return array( 'starred' => 'הצגת מועדפים בלבד', 'stats' => 'סטטיסטיקות', 'subscription' => 'ניהול הרשמות', - 'tags' => 'My labels', //TODO + 'tags' => 'My labels', //TODO - Translation 'unread' => 'הצגת מאמרים שלא נקראו בלבד', ), 'share' => 'שיתוף', 'tag' => array( - 'related' => 'תגיות קשורות', //TODO + 'related' => 'תגיות קשורות', //TODO - Translation ), ); diff --git a/app/i18n/he/install.php b/app/i18n/he/install.php index 93b8063b3..3a3e5ab12 100644 --- a/app/i18n/he/install.php +++ b/app/i18n/he/install.php @@ -4,16 +4,16 @@ return array( 'action' => array( 'finish' => 'השלמת ההתקנה', 'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.', + 'keep_install' => 'Keep previous configuration', //TODO - Translation 'next_step' => 'לשלב הבא', + 'reinstall' => 'Reinstall FreshRSS', //TODO - Translation ), 'auth' => array( - 'email_persona' => 'כתובת דואר אלקטרוני להרשמה<br /><small>(לצורך <a href="https://persona.org/" rel="external">מוזילה פרסונה</a>)</small>', 'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)', 'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)', 'none' => 'ללא (מסוכן)', 'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>', - 'password_format' => 'At least 7 characters', // @todo - 'persona' => 'מוזילה פרסונה (מודרני, דורש JavaScript)', + 'password_format' => 'At least 7 characters', //TODO - Translation 'type' => 'שיטת אימות', ), 'bdd' => array( @@ -24,15 +24,16 @@ return array( 'ok' => 'הגדרות בסיס הנתונים נשמרו.', ), 'host' => 'מארח', - 'prefix' => 'קידומת הטבלה', 'password' => 'HTTP סיסמה', + 'prefix' => 'קידומת הטבלה', 'type' => 'סוג בסיס הנתונים', 'username' => 'HTTP שם משתמש', ), 'check' => array( '_' => 'בדיקות', + 'already_installed' => 'We have detected that FreshRSS is already installed!', //TODO - Translation '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' => 'ההרשאות בתיקיית המטמון תקינות', ), 'ctype' => array( @@ -44,7 +45,7 @@ return array( 'ok' => 'יש לכם את גירסת %s של cURL', ), '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' => 'ההרשאות בתיקיית הדאטא תקינות', ), 'dom' => array( @@ -52,23 +53,27 @@ return array( 'ok' => 'הספרייה הנדרשת לסיור ב DOM מותקנת', ), '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 תקינות', ), + 'fileinfo' => array( + 'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).', //TODO - Translation + 'ok' => 'You have the fileinfo library.', //TODO - Translation + ), 'http_referer' => array( 'nok' => 'נא לדבוק שאינך פוגעת ב HTTP REFERER שלך.', 'ok' => 'הHTTP REFERER ידוע ותאם לשרת שלך.', ), '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( - '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( - 'nok' => 'You lack the Minz framework.', // @todo + 'nok' => 'You lack the Minz framework.', //TODO - Translation 'ok' => 'יש לכם את תשתית Minz', ), 'pcre' => array( @@ -79,17 +84,17 @@ return array( 'nok' => '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( 'nok' => 'גירסת PHP שלכם היא %s אך FreshRSS דורש לפחות את גירסה %s', 'ok' => 'גירסת PHP שלכם היא %s, שתואמת ל FreshRSS', ), '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( @@ -101,14 +106,17 @@ return array( 'delete_articles_after' => 'מחיקת מאמרים לאחר', 'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.', '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( '_' => 'שפה', 'choose' => 'בחירת שפה ל FreshRSS', 'defined' => 'השפה הוגדרה.', ), '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' => 'שלבים', 'title' => 'התקנה · FreshRSS', 'this_is_the_end' => 'סיום', diff --git a/app/i18n/he/sub.php b/app/i18n/he/sub.php index 711004662..e4c487b84 100644 --- a/app/i18n/he/sub.php +++ b/app/i18n/he/sub.php @@ -2,18 +2,18 @@ return 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 - '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( '_' => 'קטגוריה', 'add' => 'הוספת קטגוריה', - 'empty' => 'Empty category', // @todo + 'empty' => 'Empty category', //TODO - Translation 'new' => 'קטגוריה חדשה', ), 'feed' => array( @@ -27,7 +27,7 @@ return array( 'password' => 'HTTP סיסמה', 'username' => 'HTTP שם משתמש', ), - 'clear_cache' => 'Always clear cache', //TODO + 'clear_cache' => 'Always clear cache', //TODO - Translation 'css_help' => 'קבלת הזנות RSS קטומות (זהירות, לוקח זמן רב יותר!)', 'css_path' => 'נתיב הCSS של המאמר באתר המקורי', 'description' => 'תיאור', @@ -36,19 +36,27 @@ return array( 'informations' => 'מידע', 'keep_history' => 'מסםר מינימלי של מאמרים לשמור', 'moved_category_deleted' => 'כאשר הקטגוריה נמחקת ההזנות שבתוכה אוטומטית מקוטלגות תחת <em>%s</em>.', - 'mute' => 'mute', // TODO + 'mute' => 'mute', //TODO - Translation 'no_selected' => 'אף הזנה לא נבחרה.', 'number_entries' => '%d מאמרים', 'priority' => array( - '_' => 'Visibility', // TODO - 'archived' => 'Do not show (archived)', // TODO + '_' => 'Visibility', //TODO - Translation + 'archived' => 'Do not show (archived)', //TODO - Translation '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' => 'סטטיסטיקות', 'think_to_add' => 'ניתן להוסיף הזנות חדשות.', - 'timeout' => 'Timeout in seconds', //TODO + 'timeout' => 'Timeout in seconds', //TODO - Translation 'title' => 'כותרת', 'title_add' => 'הוספת הזנה', 'ttl' => 'אין לרענן אוטומטית יותר מ', @@ -57,8 +65,8 @@ return array( 'website' => 'אתר URL', ), '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( 'export' => 'ייצוא', @@ -75,11 +83,11 @@ return array( 'bookmark' => 'הרשמה (FreshRSS סימניית)', 'import_export' => 'יבוא / יצוא ', 'subscription_management' => 'ניהול הרשמות', - 'subscription_tools' => 'Subscription tools', // @todo + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), 'title' => array( '_' => 'ניהול הרשמות', 'feed_management' => 'ניהול הזנות RSS', - 'subscription_tools' => 'Subscription tools', // @todo + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), ); diff --git a/app/i18n/it/admin.php b/app/i18n/it/admin.php index 5696ed571..d4253e9ba 100644 --- a/app/i18n/it/admin.php +++ b/app/i18n/it/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => 'Estensione JSON presente.', ), '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( 'nok' => 'Manca il framework Minz.', @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Author', //TODO - Translation + 'community' => 'Available community extensions', //TODO - Translation + 'description' => 'Description', //TODO - Translation 'disabled' => 'Disabilitata', 'empty_list' => 'Non ci sono estensioni installate', 'enabled' => 'Abilitata', + 'latest' => 'Installed', //TODO - Translation + 'name' => 'Name', //TODO - Translation 'no_configure_view' => 'Questa estensioni non può essere configurata.', 'system' => array( '_' => 'Estensioni di sistema', 'no_rights' => 'Estensione di sistema (non hai i permessi su questo tipo)', ), 'title' => 'Estensioni', + 'update' => 'Update available', //TODO - Translation '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( '_' => 'Statistiche', @@ -158,10 +158,14 @@ return array( ), 'system' => array( '_' => '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', 'max-categories' => 'Limite categorie 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( 'help' => '0 significa che non esiste limite sui profili', 'number' => 'Numero massimo di profili', @@ -179,15 +183,15 @@ return array( 'user' => array( 'articles_and_size' => '%s articoli (%s)', 'create' => 'Crea nuovo utente', - 'delete_users' => 'Delete user', // TODO + 'delete_users' => 'Delete user', //TODO - Translation 'language' => 'Lingua', 'number' => ' %d profilo utente creato', 'numbers' => 'Sono presenti %d profili utente', 'password_form' => 'Password<br /><small>(per il login classico)</small>', 'password_format' => 'Almeno 7 caratteri', - 'selected' => 'Selected user', // TODO + 'selected' => 'Selected user', //TODO - Translation 'title' => 'Gestione utenti', - 'update_users' => 'Update user', // TODO + 'update_users' => 'Update user', //TODO - Translation 'user_list' => 'Lista utenti', 'username' => 'Nome utente', 'users' => 'Utenti', diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php index 83beb2df5..df4a5ebeb 100644 --- a/app/i18n/it/conf.php +++ b/app/i18n/it/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => 'Barra in fondo', 'entry' => 'Icone degli articoli', 'publication_date' => 'Data di pubblicazione', - 'related_tags' => 'Tags correlati', //TODO + 'related_tags' => 'Tags correlati', //TODO - Translation 'sharing' => 'Condivisione', 'top_line' => 'Barra in alto', ), @@ -28,6 +28,7 @@ return array( 'seconds' => 'secondi (0 significa nessun timeout)', 'timeout' => 'Notifica timeout HTML5', ), + 'show_nav_buttons' => 'Show the navigation buttons', //TODO - Translation 'theme' => 'Tema', 'title' => 'Visualizzazione', 'width' => array( @@ -37,12 +38,22 @@ return array( 'no_limit' => 'Nessun limite', '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( '_' => 'Ricerche personali', '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:', 'get_all' => 'Mostra tutti gli articoli', 'get_category' => 'Mostra la categoria "%s" ', @@ -53,7 +64,7 @@ return array( 'number' => 'Ricerca n°%d', 'order_asc' => 'Mostra prima gli articoli più vecchi', 'order_desc' => 'Mostra prima gli articoli più nuovi', - 'remove' => 'Remove user query', // TODO + 'remove' => 'Remove user query', //TODO - Translation 'search' => 'Cerca per "%s"', 'state_0' => 'Mostra tutti gli articoli', 'state_1' => 'Mostra gli articoli letti', @@ -73,31 +84,19 @@ return array( 'state_15' => 'Mostra tutti gli articoli', '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( '_' => 'Lettura', 'after_onread' => 'Dopo “segna tutto come letto”,', 'articles_per_page' => 'Numero di articoli per pagina', 'auto_load_more' => 'Carica articoli successivi a fondo pagina', '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”', 'display_articles_unfolded' => 'Mostra articoli aperti 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)', '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', + 'mark_updated_article_unread' => 'Segna articoli aggiornati come non letti', 'number_divided_when_reader' => 'Diviso 2 nella modalità di lettura.', 'read' => array( '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', 'unread' => 'Mostra solo non letti', ), + 'sides_close_article' => 'Clicking outside of article text area closes the article', //TODO - Translation 'sort' => array( '_' => 'Ordinamento', 'newer_first' => 'Prima i più recenti', @@ -128,7 +128,7 @@ return array( ), 'sharing' => array( '_' => 'Condivisione', - 'add' => 'Add a sharing method', // TODO + 'add' => 'Add a sharing method', //TODO - Translation 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -136,7 +136,7 @@ return array( 'g+' => 'Google+', 'more_information' => 'Ulteriori informazioni', 'print' => 'Stampa', - 'remove' => 'Remove sharing method', // TODO + 'remove' => 'Remove sharing method', //TODO - Translation 'shaarli' => 'Shaarli', 'share_name' => 'Nome condivisione', 'share_url' => 'URL condivisione', @@ -153,27 +153,30 @@ return array( 'collapse_article' => 'Collassa articoli', 'first_article' => 'Salta al primo articolo', 'focus_search' => 'Modulo di ricerca', - 'global_view' => 'Switch to global view', // TODO + 'global_view' => 'Switch to global view', //TODO - Translation 'help' => 'Mostra documentazione', 'javascript' => 'JavaScript deve essere abilitato per poter usare i comandi da tastiera', 'last_article' => 'Salta all ultimo articolo', 'load_more' => 'Carica altri articoli', - 'mark_read' => 'Segna come letto', 'mark_favorite' => 'Segna come preferito', + 'mark_read' => 'Segna come letto', '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_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation 'next_article' => 'Salta al contenuto successivo', 'normal_view' => 'Switch to normal view', // TODO 'other_action' => 'Altre azioni', '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', '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', 'user_filter' => 'Accedi alle ricerche personali', '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( 'articles_and_size' => '%s articoli (%s)', diff --git a/app/i18n/it/feedback.php b/app/i18n/it/feedback.php index b0f3a814a..ca7879904 100644 --- a/app/i18n/it/feedback.php +++ b/app/i18n/it/feedback.php @@ -50,11 +50,15 @@ return array( 'no_zip_extension' => 'Estensione ZIP non presente sul server.', '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( 'actualize' => 'Aggiorna', '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( 'created' => 'Categoria %s creata.', @@ -76,7 +80,7 @@ return array( 'already_subscribed' => 'Hai già sottoscritto <em>%s</em>', 'deleted' => 'Feed cancellato', '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', 'n_actualized' => '%d feeds aggiornati', 'n_entries_deleted' => '%d articoli cancellati', @@ -105,12 +109,8 @@ return array( 'error' => 'Utente %s non cancellato', ), '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', - ), ); diff --git a/app/i18n/it/gen.php b/app/i18n/it/gen.php index ab17441e7..9cc40ffe3 100644 --- a/app/i18n/it/gen.php +++ b/app/i18n/it/gen.php @@ -44,33 +44,28 @@ return array( ), 'date' => array( '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.', 'april' => 'aprile', + 'Aug' => '\\A\\g\\o\\s\\t\\o', 'aug' => 'ag.', 'august' => 'agosto', 'before_yesterday' => 'Meno recenti', + 'Dec' => '\\D\\i\\c\\e\\m\\b\\r\\e', 'dec' => 'dic.', 'december' => 'dicembre', + 'Feb' => '\\F\\e\\b\\b\\r\\a\\i\\o', 'feb' => 'febbr.', 'february' => 'febbraio', 'format_date' => 'j\\ %s Y', 'format_date_hour' => 'j\\ %s Y \\o\\r\\e H\\:i', 'fri' => 'Fri', + 'Jan' => '\\G\\e\\n\\u\\a\\i\\o', 'jan' => 'genn.', 'january' => 'gennaio', + 'Jul' => '\\L\\u\\g\\l\\i\\o', 'jul' => 'jul', 'july' => 'luglio', + 'Jun' => '\\G\\i\\u\\g\\n\\o', 'jun' => 'jun', 'june' => 'giugno', 'last_3_month' => 'Ultimi 3 mesi', @@ -78,17 +73,22 @@ return array( 'last_month' => 'Ultimo mese', 'last_week' => 'Ultima settimana', 'last_year' => 'Ultimo anno', + 'Mar' => '\\M\\a\\r\\z\\o', 'mar' => 'mar.', 'march' => 'marzo', + 'May' => '\\M\\a\\g\\g\\i\\o', 'may' => 'maggio', 'may_' => 'May', 'mon' => 'Mon', 'month' => 'mesi', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\r\\e', 'nov' => 'nov.', 'november' => 'novembre', + 'Oct' => '\\O\\t\\t\\o\\b\\r\\e', 'oct' => 'ott.', 'october' => 'ottobre', 'sat' => 'Sat', + 'Sep' => '\\S\\e\\t\\t\\e\\m\\b\\r\\e', 'sep' => 'sett.', 'september' => 'settembre', 'sun' => 'Sun', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -160,7 +161,6 @@ return array( 'previous' => 'Precedente', ), 'share' => array( - 'Known' => 'Siti basati su Known', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Siti basati su Known', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Stampa', 'shaarli' => 'Shaarli', diff --git a/app/i18n/it/index.php b/app/i18n/it/index.php index 909db1440..8162b1639 100644 --- a/app/i18n/it/index.php +++ b/app/i18n/it/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => 'Segna tutto come letto', 'mark_cat_read' => 'Segna la categoria come letta', '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', 'non-starred' => 'Escludi preferiti', 'normal_view' => 'Vista elenco', @@ -53,11 +53,11 @@ return array( 'starred' => 'Mostra solo preferiti', 'stats' => 'Statistiche', 'subscription' => 'Gestione sottoscrizioni', - 'tags' => 'My labels', //TODO + 'tags' => 'My labels', //TODO - Translation 'unread' => 'Mostra solo non letti', ), 'share' => 'Condividi', 'tag' => array( - 'related' => 'Tags correlati', //TODO + 'related' => 'Tags correlati', //TODO - Translation ), ); diff --git a/app/i18n/it/install.php b/app/i18n/it/install.php index 2d0a34885..0b904ab02 100644 --- a/app/i18n/it/install.php +++ b/app/i18n/it/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'Le configurazioni del database sono state salvate.', ), 'host' => 'Host', - 'prefix' => 'Prefisso tabella', 'password' => 'Password del database', + 'prefix' => 'Prefisso tabella', 'type' => 'Tipo di database', 'username' => 'Nome utente del database', ), @@ -69,8 +69,8 @@ return array( 'ok' => 'You have a recommended library to parse JSON.', ), '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( 'nok' => 'Manca il framework Minz.', @@ -85,7 +85,6 @@ return array( 'ok' => 'PDO e altri driver supportati (pdo_mysql, pdo_sqlite, pdo_pgsql).', ), 'php' => array( - '_' => 'Installazione PHP', 'nok' => 'Versione di PHP %s FreshRSS richiede almeno la versione %s.', 'ok' => 'Versione di PHP %s, compatibile con FreshRSS.', ), diff --git a/app/i18n/it/sub.php b/app/i18n/it/sub.php index b22340c9b..6faa48d63 100644 --- a/app/i18n/it/sub.php +++ b/app/i18n/it/sub.php @@ -2,13 +2,13 @@ return 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 - 'label' => 'Subscribe',// TODO - 'title' => 'Bookmarklet',// TODO + 'label' => 'Subscribe', //TODO - Translation + 'title' => 'Bookmarklet', //TODO - Translation ), 'category' => array( '_' => 'Categoria', @@ -27,7 +27,7 @@ return array( 'password' => 'HTTP password', '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_path' => 'Percorso del foglio di stile CSS del sito di origine', 'description' => 'Descrizione', @@ -36,30 +36,37 @@ return array( 'informations' => 'Informazioni', '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>.', - 'mute' => 'mute', // TODO + 'mute' => 'mute', //TODO - Translation 'no_selected' => 'Nessun feed selezionato.', 'number_entries' => '%d articoli', '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', 'think_to_add' => 'Aggiungi feed.', - 'timeout' => 'Timeout in seconds', //TODO + 'timeout' => 'Timeout in seconds', //TODO - Translation 'title' => 'Titolo', 'title_add' => 'Aggiungi RSS feed', 'ttl' => 'Non aggiornare automaticamente piu di', 'url' => 'Feed URL', 'validator' => 'Controlla la validita del feed ', 'website' => 'URL del sito', - 'pubsubhubbub' => 'Notifica istantanea 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 - '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( 'export' => 'Esporta', @@ -76,11 +83,11 @@ return array( 'bookmark' => 'Bookmark (trascina nei preferiti)', 'import_export' => 'Importa / esporta', 'subscription_management' => 'Gestione sottoscrizioni', - 'subscription_tools' => 'Subscription tools',// TODO + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), 'title' => array( '_' => 'Gestione sottoscrizioni', 'feed_management' => 'Gestione RSS feeds', - 'subscription_tools' => 'Subscription tools',// TODO + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), ); diff --git a/app/i18n/kr/admin.php b/app/i18n/kr/admin.php index bc65b3fa2..532fe30a5 100644 --- a/app/i18n/kr/admin.php +++ b/app/i18n/kr/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => 'JSON 확장 기능이 설치되어 있습니다.', ), '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( 'nok' => 'Minz 프레임워크를 찾을 수 없습니다.', @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => '제작자', + 'community' => '사용 가능한 커뮤니티 확장 기능들', + 'description' => '설명', 'disabled' => '비활성화됨', 'empty_list' => '설치된 확장 기능이 없습니다', 'enabled' => '활성화됨', + 'latest' => '설치됨', + 'name' => '이름', 'no_configure_view' => '이 확장 기능은 설정이 없습니다.', 'system' => array( '_' => '시스템 확장 기능', 'no_rights' => '시스템 확장 기능 (이 확장 기능에 대한 권한이 없습니다)', ), 'title' => '확장 기능', + 'update' => '업데이트 있음', 'user' => '사용자 확장 기능', - 'community' => '사용 가능한 커뮤니티 확장 기능들', - 'name' => '이름', 'version' => '버전', - 'description' => '설명', - 'author' => '제작자', - 'latest' => '설치됨', - 'update' => '업데이트 있음', ), 'stats' => array( '_' => '통계', @@ -162,6 +162,10 @@ return array( 'instance-name' => '인스턴스 이름', 'max-categories' => '사용자별 카테고리 개수 제한', 'max-feeds' => '사용자별 피드 개수 제한', + 'cookie-duration' => array( + 'help' => 'in seconds', // @todo translate + 'number' => 'Duration to keep logged in', // @todo translate + ), 'registration' => array( 'help' => '0: 제한 없음', 'number' => '계정 최대 개수', diff --git a/app/i18n/kr/conf.php b/app/i18n/kr/conf.php index f26e2cf09..5c3d95d17 100644 --- a/app/i18n/kr/conf.php +++ b/app/i18n/kr/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => '하단', 'entry' => '문서 아이콘', 'publication_date' => '발행일', - 'related_tags' => '관련 태그', //TODO + 'related_tags' => '관련 태그', 'sharing' => '공유', 'top_line' => '상단', ), @@ -28,6 +28,7 @@ return array( 'seconds' => '초 (0: 타임아웃 없음)', 'timeout' => 'HTML5 알림 타임아웃', ), + 'show_nav_buttons' => '내비게이션 버튼 보이기', 'theme' => '테마', 'title' => '표시', 'width' => array( @@ -37,7 +38,17 @@ return array( 'no_limit' => '제한 없음', '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( '_' => '사용자 쿼리', @@ -73,31 +84,19 @@ return array( 'state_15' => '모든 글 표시', 'title' => '사용자 쿼리', ), - 'profile' => array( - '_' => '프로필 관리', - 'delete' => array( - '_' => '계정 삭제', - 'warn' => '당신의 계정과 관련된 모든 데이터가 삭제됩니다.', - ), - 'password_api' => 'API 암호<br /><small>(예: 모바일 애플리케이션)</small>', - 'password_form' => '암호<br /><small>(웹폼 로그인 방식 사용시)</small>', - 'password_format' => '7 글자 이상이어야 합니다', - 'title' => '프로필', - ), 'reading' => array( '_' => '읽기', 'after_onread' => '“모두 읽음으로 표시” 후,', 'articles_per_page' => '페이지당 글 수', 'auto_load_more' => '페이지 하단에 다다르면 글 더 불러오기', 'auto_remove_article' => '글을 읽은 후 숨기기', - 'mark_updated_article_unread' => '갱신 된 글을 읽지 않음으로 표시', 'confirm_enabled' => '“모두 읽음으로 표시” 실행시 확인 창 표시', 'display_articles_unfolded' => '글을 펼쳐진 상태로 보여주기', 'display_categories_unfolded' => '카테고리를 접힌 상태로 보여주기', 'hide_read_feeds' => '읽지 않은 글이 없는 카테고리와 피드 감추기 (“모든 글 표시”가 설정된 경우 동작하지 않습니다)', 'img_with_lazyload' => '그림을 불러오는 데에 "lazy load" 모드 사용하기', - 'sides_close_article' => '글 영역 바깥을 클릭하면 글 접기', 'jump_next' => '다음 읽지 않은 항목으로 이동 (피드 또는 카테고리)', + 'mark_updated_article_unread' => '갱신 된 글을 읽지 않음으로 표시', 'number_divided_when_reader' => '읽기 모드에서는 절반만 표시됩니다.', 'read' => array( 'article_open_on_website' => '글이 게재된 웹사이트를 방문했을 때', @@ -112,6 +111,7 @@ return array( 'all_articles' => '모든 글 표시', 'unread' => '읽지 않은 글만 표시', ), + 'sides_close_article' => '글 영역 바깥을 클릭하면 글 접기', 'sort' => array( '_' => '정렬 순서', 'newer_first' => '최근 글 먼저', @@ -158,10 +158,11 @@ return array( 'javascript' => '단축키를 사용하기 위해선 자바스크립트를 사용하도록 설정하여야 합니다', 'last_article' => '마지막 글 보기', 'load_more' => '글 더 불러오기', - 'mark_read' => '읽음으로 표시', 'mark_favorite' => '즐겨찾기에 등록', + 'mark_read' => '읽음으로 표시', 'navigation' => '탐색', 'navigation_help' => '"Shift" 키를 누른 상태에선 탐색 단축키가 피드에 적용됩니다.<br/>"Alt" 키를 누른 상태에선 탐색 단축키가 카테고리에 적용됩니다.', + 'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation 'next_article' => '다음 글 보기', 'normal_view' => '일반 모드로 전환', 'other_action' => '다른 동작', @@ -170,6 +171,8 @@ return array( 'rss_view' => '새 탭에서 RSS 피드 열기', 'see_on_website' => '글이 게재된 웹사이트에서 보기', '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' => '단축키', 'user_filter' => '사용자 필터 사용하기', 'user_filter_help' => '사용자 필터가 하나만 설정되어 있다면 해당 필터를 사용하고, 그렇지 않다면 필터를 번호로 선택할 수 있습니다.', diff --git a/app/i18n/kr/feedback.php b/app/i18n/kr/feedback.php index 12cd673ff..550904894 100644 --- a/app/i18n/kr/feedback.php +++ b/app/i18n/kr/feedback.php @@ -50,11 +50,15 @@ return array( 'no_zip_extension' => 'ZIP 확장 기능을 서버에서 찾을 수 없습니다.', 'zip_error' => 'ZIP 파일을 불러오는 동안 문제가 발생했습니다.', ), + 'profile' => array( + 'error' => '프로필을 변경할 수 없습니다', + 'updated' => '프로필을 변경했습니다', + ), 'sub' => array( 'actualize' => '피드를 가져오는 중입니다', '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( 'created' => '%s 카테고리가 생성되었습니다.', @@ -109,8 +113,4 @@ return array( 'error' => '사용자 %s의 정보가 변경되지 않았습니다', ), ), - 'profile' => array( - 'error' => '프로필을 변경할 수 없습니다', - 'updated' => '프로필을 변경했습니다', - ), ); diff --git a/app/i18n/kr/gen.php b/app/i18n/kr/gen.php index 6a461bdac..86a50e9c4 100644 --- a/app/i18n/kr/gen.php +++ b/app/i18n/kr/gen.php @@ -44,33 +44,28 @@ return 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' => '4월', 'april' => '4월', + 'Aug' => '\\A\\u\\g\\u\\s\\t', 'aug' => '8월', 'august' => '8월', 'before_yesterday' => '어제 이전', + 'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r', 'dec' => '12월', 'december' => '12월', + 'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y', 'feb' => '2월', 'february' => '2월', 'format_date' => 'Y년 m월 d일', 'format_date_hour' => 'Y년 m월 d일 H시 i분', 'fri' => '금', + 'Jan' => '\\J\\a\\n\\u\\a\\r\\y', 'jan' => '1월', 'january' => '1월', + 'Jul' => '\\J\\u\\l\\y', 'jul' => '7월', 'july' => '7월', + 'Jun' => '\\J\\u\\n\\e', 'jun' => '6월', 'june' => '6월', 'last_3_month' => '최근 3 개월', @@ -78,17 +73,22 @@ return array( 'last_month' => '최근 한 달', 'last_week' => '최근 한 주', 'last_year' => '최근 일 년', + 'Mar' => '\\M\\a\\r\\c\\h', 'mar' => '3월', 'march' => '3월', + 'May' => '\\M\\a\\y', 'may' => '5월', 'may_' => '5월', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r', 'mon' => '월', 'month' => '개월', 'nov' => '11월', 'november' => '11월', + 'Oct' => '\\O\\c\\t\\o\\b\\e\\r', 'oct' => '10월', 'october' => '10월', 'sat' => '토', + 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', 'sep' => '9월', 'september' => '9월', 'sun' => '일', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -160,7 +161,6 @@ return array( 'previous' => 'Previous', ), 'share' => array( - 'Known' => 'Known based sites', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => '메일', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Known based sites', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => '인쇄', 'shaarli' => 'Shaarli', diff --git a/app/i18n/kr/index.php b/app/i18n/kr/index.php index 87cc12eca..3c63fd664 100644 --- a/app/i18n/kr/index.php +++ b/app/i18n/kr/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => '모두 읽음으로 표시', 'mark_cat_read' => '카테고리를 읽음으로 표시', 'mark_feed_read' => '피드를 읽음으로 표시', - 'mark_selection_unread' => 'Mark selection as unread', //TODO + 'mark_selection_unread' => 'Mark selection as unread', //TODO - Translation 'newer_first' => '최근 글 먼저', 'non-starred' => '즐겨찾기를 제외하고 표시', 'normal_view' => '일반 모드', @@ -53,11 +53,11 @@ return array( 'starred' => '즐겨찾기만 표시', 'stats' => '통계', 'subscription' => '구독 관리', - 'tags' => 'My labels', //TODO + 'tags' => 'My labels', //TODO - Translation 'unread' => '읽지 않은 글만 표시', ), 'share' => '공유', 'tag' => array( - 'related' => '관련 태그', //TODO + 'related' => '관련 태그', //TODO - Translation ), ); diff --git a/app/i18n/kr/install.php b/app/i18n/kr/install.php index 03a8ccdbe..6b60f6ffd 100644 --- a/app/i18n/kr/install.php +++ b/app/i18n/kr/install.php @@ -24,8 +24,8 @@ return array( 'ok' => '데이터베이스 설정이 저장되었습니다.', ), 'host' => '데이터베이스 서버', - 'prefix' => '테이블 접두어', 'password' => '데이터베이스 암호', + 'prefix' => '테이블 접두어', 'type' => '데이터베이스 종류', 'username' => '데이터베이스 사용자 이름', ), @@ -69,8 +69,8 @@ return array( 'ok' => 'JSON 확장 기능이 설치되어 있습니다.', ), '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( 'nok' => 'Minz 프레임워크를 찾을 수 없습니다.', diff --git a/app/i18n/kr/sub.php b/app/i18n/kr/sub.php index ee6b25e3f..463496c57 100644 --- a/app/i18n/kr/sub.php +++ b/app/i18n/kr/sub.php @@ -27,7 +27,7 @@ return array( 'password' => 'HTTP 암호', 'username' => 'HTTP 사용자 이름', ), - 'clear_cache' => 'Always clear cache', //TODO + 'clear_cache' => 'Always clear cache', //TODO - Translation 'css_help' => '글의 일부가 포함된 RSS 피드를 가져옵니다 (주의, 시간이 좀 더 걸립니다!)', 'css_path' => '웹사이트 상의 글 본문에 해당하는 CSS 경로', 'description' => '설명', @@ -45,6 +45,14 @@ return array( 'main_stream' => '메인 스트림에 표시하기', '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 유효성 검사', 'stats' => '통계', 'think_to_add' => '피드를 추가할 수 있습니다.', @@ -55,7 +63,6 @@ return array( 'url' => '피드 URL', 'validator' => '피드 유효성 검사', 'website' => '웹사이트 URL', - 'pubsubhubbub' => 'PubSubHubbub을 사용한 즉시 알림', ), '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>의 설명을 따르세요.', diff --git a/app/i18n/nl/admin.php b/app/i18n/nl/admin.php index f40db7bcb..8a63b885b 100644 --- a/app/i18n/nl/admin.php +++ b/app/i18n/nl/admin.php @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Auteur', + 'community' => 'Gebruikersuitbreidingen beschikbaar', + 'description' => 'Beschrijving', 'disabled' => 'Uitgeschakeld', 'empty_list' => 'Er zijn geïnstalleerde uitbreidingen', 'enabled' => 'Ingeschakeld', + 'latest' => 'Geïnstalleerd', + 'name' => 'Naam', 'no_configure_view' => 'Deze uitbreiding kan niet worden geconfigureerd.', 'system' => array( '_' => 'Systeemuitbreidingen', 'no_rights' => 'Systeemuitbreidingen (U hebt hier geen rechten op)', ), 'title' => 'Uitbreidingen', + 'update' => 'Update beschikbaar', 'user' => 'Gebruikersuitbreidingen', - 'community' => 'Gebruikersuitbreidingen beschikbaar', - 'name' => 'Naam', 'version' => 'Versie', - 'description' => 'Beschrijving', - 'author' => 'Auteur', - 'latest' => 'Geïnstalleerd', - 'update' => 'Update beschikbaar', ), 'stats' => array( '_' => 'Statistieken', @@ -162,6 +162,10 @@ return array( 'instance-name' => 'Voorbeeld naam', 'max-categories' => 'Categoriën 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( 'help' => '0 betekent geen account limiet', 'number' => 'Maximum aantal accounts', @@ -185,11 +189,6 @@ return array( 'numbers' => 'Er zijn %d accounts gemaakt', 'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier loginmethode)</small>', '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', 'title' => 'Beheer gebruikers', 'update_users' => 'Gebruiker bijwerken', diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php index 883d932ab..ba21fc889 100644 --- a/app/i18n/nl/conf.php +++ b/app/i18n/nl/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => 'Onderaan', 'entry' => 'Artikel pictogrammen', 'publication_date' => 'Publicatie datum', - 'related_tags' => 'Gerelateerde labels', //TODO + 'related_tags' => 'Gerelateerde labels', 'sharing' => 'Delen', 'top_line' => 'Bovenaan', ), @@ -28,6 +28,7 @@ return array( 'seconds' => 'seconden (0 betekent geen stop)', 'timeout' => 'HTML5 notificatie stop', ), + 'show_nav_buttons' => 'Toon navigatieknoppen', 'theme' => 'Thema', 'title' => 'Opmaak', 'width' => array( @@ -37,7 +38,17 @@ return array( 'no_limit' => 'Geen limiet', '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( '_' => 'Gebruikersquery\'s (informatie aanvragen)', @@ -73,17 +84,6 @@ return array( 'state_15' => 'Toon alle artikelen', '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( '_' => 'Lezen', 'after_onread' => 'Na “markeer alles als gelezen”,', @@ -95,7 +95,6 @@ return array( '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)', '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)', 'mark_updated_article_unread' => 'Markeer vernieuwd artikel als ongelezen', 'number_divided_when_reader' => 'Gedeeld door 2 in de lees modus.', @@ -112,6 +111,7 @@ return array( 'all_articles' => 'Bekijk alle artikelen', 'unread' => 'Bekijk alleen ongelezen', ), + 'sides_close_article' => 'Sluit het artikel door buiten de artikeltekst te klikken', 'sort' => array( '_' => 'Sorteer volgorde', 'newer_first' => 'Nieuwste eerst', @@ -158,10 +158,11 @@ return array( 'javascript' => 'JavaScript moet geactiveerd zijn om verwijzingen te gebruiken', 'last_article' => 'Spring naar laatste artikel', 'load_more' => 'Laad meer artikelen', - 'mark_read' => 'Markeer als gelezen', 'mark_favorite' => 'Markeer als favoriet', + 'mark_read' => 'Markeer als gelezen', '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_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation 'next_article' => 'Spring naar volgende artikel', 'normal_view' => 'Schakel naar gewoon aanzicht', 'other_action' => 'Andere acties', @@ -170,6 +171,8 @@ return array( 'rss_view' => 'Open RSS-aanzicht in een nieuwe tab', 'see_on_website' => 'Bekijk op originale website', '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', '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.', diff --git a/app/i18n/nl/feedback.php b/app/i18n/nl/feedback.php index b16232b84..07ac7e89d 100644 --- a/app/i18n/nl/feedback.php +++ b/app/i18n/nl/feedback.php @@ -50,6 +50,10 @@ return array( '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.', ), + 'profile' => array( + 'error' => 'Uw profiel kan niet worden aangepast', + 'updated' => 'Uw profiel is aangepast', + ), 'sub' => array( 'actualize' => 'Actualiseren', 'articles' => array( @@ -108,10 +112,5 @@ return array( '_' => 'Gebruiker %s is 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', ), ); diff --git a/app/i18n/nl/gen.php b/app/i18n/nl/gen.php index fdc4338c3..bdf2e0abd 100644 --- a/app/i18n/nl/gen.php +++ b/app/i18n/nl/gen.php @@ -44,33 +44,28 @@ return array( ), 'date' => array( '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', 'april' => 'Apr', + 'Aug' => '\\A\\u\\g\\u\\s\\t\\u\\s', 'aug' => 'aug', 'august' => 'Aug', 'before_yesterday' => 'Ouder', + 'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r', 'dec' => 'dec', 'december' => 'Dec', + 'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\i', 'feb' => 'feb', 'february' => 'Feb', 'format_date' => 'j %s Y', 'format_date_hour' => 'j %s Y \\o\\m H\\:i', 'fri' => 'Vr', + 'Jan' => '\\J\\a\\n\\u\\a\\r\\i', 'jan' => 'jan', 'january' => 'Jan', + 'Jul' => '\\J\\u\\l\\i', 'jul' => 'jul', 'july' => 'Jul', + 'Jun' => '\\J\\u\\n\\i', 'jun' => 'jun', 'june' => 'Jun', 'last_3_month' => 'Laatste drie maanden', @@ -78,17 +73,22 @@ return array( 'last_month' => 'Vorige maand', 'last_week' => 'Vorige week', 'last_year' => 'Vorig jaar', + 'Mar' => '\\M\\a\\a\\r\\t', 'mar' => 'mrt', 'march' => 'Mrt', + 'May' => '\\M\\e\\i', 'may' => 'Mei', 'may_' => 'Mei', 'mon' => 'Ma', 'month' => 'maanden', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r', 'nov' => 'nov', 'november' => 'Nov', + 'Oct' => '\\O\\k\\t\\o\\b\\e\\r', 'oct' => 'okt', 'october' => 'Okt', 'sat' => 'Za', + 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', 'sep' => 'sep', 'september' => 'Sep', 'sun' => 'Zo', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -160,7 +161,6 @@ return array( 'previous' => 'Vorige', ), 'share' => array( - 'Known' => 'Known based sites', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Known based sites', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Print', 'shaarli' => 'Shaarli', diff --git a/app/i18n/nl/index.php b/app/i18n/nl/index.php index 33fec43c0..c2b550647 100644 --- a/app/i18n/nl/index.php +++ b/app/i18n/nl/index.php @@ -53,10 +53,11 @@ return array( 'starred' => 'Laat alleen favorieten zien', 'stats' => 'Statistieken', 'subscription' => 'Abonnementen beheer', + 'tags' => 'My labels', //TODO - Translation 'unread' => 'Laat alleen ongelezen zien', ), 'share' => 'Delen', 'tag' => array( - 'related' => 'Verwante labels', //TODO + 'related' => 'Verwante labels', //TODO - Translation ), ); diff --git a/app/i18n/nl/install.php b/app/i18n/nl/install.php index 2d2f38913..6597c8146 100644 --- a/app/i18n/nl/install.php +++ b/app/i18n/nl/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'Database configuratie is opgeslagen.', ), 'host' => 'Host', - 'prefix' => 'Tabel voorvoegsel', 'password' => 'Database wachtwoord', + 'prefix' => 'Tabel voorvoegsel', 'type' => 'Type database', 'username' => 'Database gebruikersnaam', ), diff --git a/app/i18n/nl/sub.php b/app/i18n/nl/sub.php index fec7fb4e7..36c96b53f 100644 --- a/app/i18n/nl/sub.php +++ b/app/i18n/nl/sub.php @@ -27,7 +27,7 @@ return array( 'password' => 'HTTP wachtwoord', '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_path' => 'Artikelen CSS pad op originele website', 'description' => 'Omschrijving', @@ -45,7 +45,14 @@ return array( 'main_stream' => 'Zichtbaar in het overzicht', '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', 'stats' => 'Statistieken', 'think_to_add' => 'Voeg wat feeds toe.', diff --git a/app/i18n/oc/admin.php b/app/i18n/oc/admin.php new file mode 100644 index 000000000..4a47374d7 --- /dev/null +++ b/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', + ), +); diff --git a/app/i18n/oc/conf.php b/app/i18n/oc/conf.php new file mode 100644 index 000000000..346f796e1 --- /dev/null +++ b/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', + ), +); diff --git a/app/i18n/oc/feedback.php b/app/i18n/oc/feedback.php new file mode 100644 index 000000000..7f7d05dbd --- /dev/null +++ b/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', + ), + ), +); diff --git a/app/i18n/oc/gen.php b/app/i18n/oc/gen.php new file mode 100644 index 000000000..ffe10941d --- /dev/null +++ b/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', + ), +); diff --git a/app/i18n/oc/index.php b/app/i18n/oc/index.php new file mode 100644 index 000000000..5211fd24a --- /dev/null +++ b/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', + ), +); diff --git a/app/i18n/oc/install.php b/app/i18n/oc/install.php new file mode 100644 index 000000000..5d4639ab4 --- /dev/null +++ b/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', +); diff --git a/app/i18n/oc/sub.php b/app/i18n/oc/sub.php new file mode 100644 index 000000000..f9ddf339a --- /dev/null +++ b/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', + ), +); diff --git a/app/i18n/pt-br/admin.php b/app/i18n/pt-br/admin.php index 51c5d381f..82559c67b 100644 --- a/app/i18n/pt-br/admin.php +++ b/app/i18n/pt-br/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => 'Você tem a extensão JSON.', ), '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( 'nok' => 'Não foi possível encontrar o framework Minz.', @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Author', //TODO - Translation + 'community' => 'Available community extensions', //TODO - Translation + 'description' => 'Description', //TODO - Translation 'disabled' => 'Desabilitado', 'empty_list' => 'Não há extensões instaladas', 'enabled' => 'Habilitada', + 'latest' => 'Installed', //TODO - Translation + 'name' => 'Name', //TODO - Translation 'no_configure_view' => 'Esta extensão não pode ser configurada.', 'system' => array( '_' => 'Extensões do sistema', 'no_rights' => 'Extensões do sistema (Você não tem direitos para isto)', ), 'title' => 'Extensões', + 'update' => 'Update available', //TODO - Translation '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( '_' => 'Estatísticas', @@ -162,6 +162,10 @@ return array( 'instance-name' => 'Nome da instância', 'max-categories' => 'Limite de categorias 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( 'help' => '0 significa que não há limite para a conta', 'number' => 'Máximo número de contas', @@ -179,15 +183,15 @@ return array( 'user' => array( 'articles_and_size' => '%s artigos (%s)', 'create' => 'Criar novo usuário', - 'delete_users' => 'Delete user', // TODO + 'delete_users' => 'Delete user', //TODO - Translation 'language' => 'Idioma', 'number' => 'Há %d conta criada', 'numbers' => 'Há %d contas criadas', 'password_form' => 'Senha<br /><small>(para o login pelo método do formulário)</small>', 'password_format' => 'Ao menos 7 caracteres', - 'selected' => 'Selected user', // TODO + 'selected' => 'Selected user', //TODO - Translation 'title' => 'Gerenciar usuários', - 'update_users' => 'Update user', // TODO + 'update_users' => 'Update user', //TODO - Translation 'user_list' => 'Lista de usuários', 'username' => 'Usuário', 'users' => 'Usuários', diff --git a/app/i18n/pt-br/conf.php b/app/i18n/pt-br/conf.php index 2547a8624..ca365db5b 100644 --- a/app/i18n/pt-br/conf.php +++ b/app/i18n/pt-br/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => 'Linha inferior', 'entry' => 'Ícones de artigos', 'publication_date' => 'Data da publicação', - 'related_tags' => 'Tags relacionadas', //TODO + 'related_tags' => 'Tags relacionadas', //TODO - Translation 'sharing' => 'Compartilhar', 'top_line' => 'Linha superior', ), @@ -28,6 +28,7 @@ return array( 'seconds' => 'segundos (0 significa sem timeout)', 'timeout' => 'Notificação em HTML5 de timeout', ), + 'show_nav_buttons' => 'Show the navigation buttons', //TODO - Translation 'theme' => 'Tema', 'title' => 'Exibição', 'width' => array( @@ -37,12 +38,22 @@ return array( 'no_limit' => 'Sem lmite', '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( '_' => 'Queries do usuário', '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:', 'get_all' => 'Mostrar todos os artigos', 'get_category' => 'Visualizar "%s" categoria', @@ -53,7 +64,7 @@ return array( 'number' => 'Query n°%d', 'order_asc' => 'Exibir artigos mais antigos primeiro', 'order_desc' => 'Exibir artigos mais novos primeiro', - 'remove' => 'Remove user query', // TODO + 'remove' => 'Remove user query', //TODO - Translation 'search' => 'Busca por "%s"', 'state_0' => 'Exibir todos os artigos', 'state_1' => 'Exibir artigos lidos', @@ -73,31 +84,19 @@ return array( 'state_15' => 'Exibir todos os artigos', '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( '_' => 'Leitura', 'after_onread' => 'Depois de "marcar todos como lido",', 'articles_per_page' => 'Número de artigos por página', 'auto_load_more' => 'Carregar mais artigos no final da página', '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"', 'display_articles_unfolded' => 'Mostrar aritogs abertos 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”)', '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)', + 'mark_updated_article_unread' => 'Marcar artigos atualizados como não lidos', 'number_divided_when_reader' => 'Dividido por 2 no modo de leitura .', 'read' => array( 'article_open_on_website' => 'quando o artigo é aberto no site original', @@ -112,6 +111,7 @@ return array( 'all_articles' => 'Exibir todos os artigos', 'unread' => 'Exibir apenas não lido', ), + 'sides_close_article' => 'Clicando fora da área do texto do artigo fecha o mesmo', 'sort' => array( '_' => 'Ordem de visualização', 'newer_first' => 'Novos primeiro', @@ -128,7 +128,7 @@ return array( ), 'sharing' => array( '_' => 'Compartilhando', - 'add' => 'Add a sharing method', // TODO + 'add' => 'Add a sharing method', //TODO - Translation 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -136,7 +136,7 @@ return array( 'g+' => 'Google+', 'more_information' => 'Mais informação', 'print' => 'Imprimir', - 'remove' => 'Remove sharing method', // TODO + 'remove' => 'Remove sharing method', //TODO - Translation 'shaarli' => 'Shaarli', 'share_name' => 'Nome de visualização para compartilhar', 'share_url' => 'URL utilizada para compartilhar', @@ -153,27 +153,30 @@ return array( 'collapse_article' => 'Fechar', 'first_article' => 'Ir para o primeiro artigo', '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', 'javascript' => 'JavaScript deve ser habilitado para utilizar atalhos', 'last_article' => 'Ir para o último artigo', 'load_more' => 'Carregar mais artigos', - 'mark_read' => 'Marcar como lido', 'mark_favorite' => 'Marcar como favorito', + 'mark_read' => 'Marcar como lido', '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_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation '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', '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', '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', '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.', - 'views' => 'Views', // TODO + 'views' => 'Views', //TODO - Translation ), 'user' => array( 'articles_and_size' => '%s artigos (%s)', diff --git a/app/i18n/pt-br/feedback.php b/app/i18n/pt-br/feedback.php index a2d66384e..816bbf43b 100644 --- a/app/i18n/pt-br/feedback.php +++ b/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.', '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( 'actualize' => 'Atualizando', '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( 'created' => 'Categoria %s foi criada.', @@ -76,7 +80,7 @@ return array( 'already_subscribed' => 'Você já está inscrito no <em>%s</em>', 'deleted' => 'o Feed foi deletado', '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', 'n_actualized' => '%d feeds foram atualizados', 'n_entries_deleted' => '%d artigos foram deletados', @@ -105,12 +109,8 @@ return array( 'error' => 'Usuário %s não pode ser deletado', ), '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', - ), ); diff --git a/app/i18n/pt-br/gen.php b/app/i18n/pt-br/gen.php index 59218597b..46ae53eb4 100644 --- a/app/i18n/pt-br/gen.php +++ b/app/i18n/pt-br/gen.php @@ -19,7 +19,7 @@ return array( 'see_website' => 'Ver o site', 'submit' => 'Enviar', 'truncate' => 'Deletar todos os artigos', - 'update' => 'Update', // TODO + 'update' => 'Update', //TODO - Translation ), 'auth' => array( 'email' => 'Endereço de e-mail', @@ -44,33 +44,28 @@ return array( ), 'date' => array( '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', 'april' => 'Abr', + 'Aug' => '\\A\\g\\o\\s\\t\\o', 'aug' => 'ago', 'august' => 'Ago', 'before_yesterday' => 'Antes de ontem', + 'Dec' => '\\D\\e\\z\\e\\m\\b\\r\\o', 'dec' => 'dez', 'december' => 'Dez', + 'Feb' => '\\F\\e\\v\\e\\r\\e\\i\\r\\o', 'feb' => 'fev', 'february' => 'Fev', 'format_date' => 'j \\d\\e %s \\d\\e Y', 'format_date_hour' => 'j \\d\\e %s \\d\\e Y\\, H\\:i', 'fri' => 'Sex', + 'Jan' => '\\J\\a\\n\\e\\i\\r\\o', 'jan' => 'jan', 'january' => 'Jan', + 'Jul' => '\\J\\u\\l\\h\\o', 'jul' => 'jul', 'july' => 'Jul', + 'Jun' => '\\J\\u\\n\\h\\o', 'jun' => 'jun', 'june' => 'Jun', 'last_3_month' => 'Últimos três meses', @@ -78,16 +73,22 @@ return array( 'last_month' => 'Últimos mês', 'last_week' => 'Última semana', 'last_year' => 'Último ano', + 'Mar' => '\\M\\a\\r\\ç\\o', 'mar' => 'mar', 'march' => 'Mar', + 'May' => '\\M\\a\\i\\o', 'may' => 'Mai', + 'may_' => 'Mai', 'mon' => 'Seg', 'month' => 'meses', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\r\\o', 'nov' => 'nov', 'november' => 'Nov', + 'Oct' => '\\O\\u\\t\\u\\b\\r\\o', 'oct' => 'out', 'october' => 'Out', 'sat' => 'Sab', + 'Sep' => '\\S\\e\\t\\e\\m\\b\\r\\o', 'sep' => 'set', 'september' => 'Set', 'sun' => 'Dom', @@ -123,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -159,7 +161,6 @@ return array( 'previous' => 'Anterior', ), 'share' => array( - 'Known' => 'Known based sites', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -167,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Known based sites', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Imprimir', 'shaarli' => 'Shaarli', diff --git a/app/i18n/pt-br/index.php b/app/i18n/pt-br/index.php index 9f98902ed..e5807ed95 100644 --- a/app/i18n/pt-br/index.php +++ b/app/i18n/pt-br/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => 'Marcar todos como lidos', 'mark_cat_read' => 'Marcar categoria como lida', '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', 'non-starred' => 'Mostrar todos, exceto favoritos', 'normal_view' => 'visualização normal', @@ -53,10 +53,11 @@ return array( 'starred' => 'Mostrar apenas os favoritos', 'stats' => 'Estatísticas', 'subscription' => 'Gerenciamento de inscrições', + 'tags' => 'My labels', //TODO - Translation 'unread' => 'Mostrar apenas os não lidos', ), 'share' => 'Compartilhar', 'tag' => array( - 'related' => 'Tags relacionadas', //TODO + 'related' => 'Tags relacionadas', //TODO - Translation ), ); diff --git a/app/i18n/pt-br/install.php b/app/i18n/pt-br/install.php index 65bddf62c..d99a09364 100644 --- a/app/i18n/pt-br/install.php +++ b/app/i18n/pt-br/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'Configurações do banco de dados foram salvas.', ), 'host' => 'Host', - 'prefix' => 'Prefixo da tabela', 'password' => 'Senha do banco de dados', + 'prefix' => 'Prefixo da tabela', 'type' => 'Tipo do banco de dados', 'username' => 'Usuário do banco de dados', ), @@ -69,8 +69,8 @@ return array( 'ok' => 'Você tem a extensão JSON.', ), '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( 'nok' => 'Não foi possível encontrar o framework Minz.', diff --git a/app/i18n/pt-br/sub.php b/app/i18n/pt-br/sub.php index daa24e8f3..78684c14c 100644 --- a/app/i18n/pt-br/sub.php +++ b/app/i18n/pt-br/sub.php @@ -2,13 +2,13 @@ return 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 - '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( '_' => 'Categoria', @@ -27,7 +27,7 @@ return array( 'password' => 'Senha 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_path' => 'Caminho do CSS do artigo no site original', 'description' => 'Descrição', @@ -36,26 +36,33 @@ return array( 'informations' => 'Informações', '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>.', - 'mute' => 'mute', // TODO + 'mute' => 'mute', //TODO - Translation 'no_selected' => 'Nenhum feed selecionado.', 'number_entries' => '%d artigos', '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', - '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', 'think_to_add' => 'Você deve adicionar alguns feeds.', - 'timeout' => 'Timeout in seconds', //TODO + 'timeout' => 'Timeout in seconds', //TODO - Translation 'title' => 'Título', 'title_add' => 'Adicionar o RSS feed', 'ttl' => 'Não atualize automáticamente mais que', 'url' => 'Feed URL', 'validator' => 'Verifique a validade do feed', 'website' => 'URL do site', - 'pubsubhubbub' => 'Notificação instantânea com PubSubHubbub', ), 'import_export' => array( 'export' => 'Exportar', diff --git a/app/i18n/ru/admin.php b/app/i18n/ru/admin.php index 91da8adcf..c9a7d6683 100644 --- a/app/i18n/ru/admin.php +++ b/app/i18n/ru/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => 'У вас установлена библиотека для работы с JSON.', ), '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( 'nok' => 'У вас не установлен фрейворк Minz.', @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Author', //TODO - Translation + 'community' => 'Available community extensions', //TODO - Translation + 'description' => 'Description', //TODO - Translation 'disabled' => 'Отключены', 'empty_list' => 'Расширения не установлены', 'enabled' => 'Включены', + 'latest' => 'Installed', //TODO - Translation + 'name' => 'Name', //TODO - Translation 'no_configure_view' => 'Это расширение нельзя настроить.', 'system' => array( '_' => 'Системные расширения', 'no_rights' => 'Системные расширения (у вас нет к ним доступа)', ), 'title' => 'Расширения', + 'update' => 'Update available', //TODO - Translation '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( '_' => 'Статистика', @@ -162,6 +162,10 @@ return array( 'instance-name' => 'Название этого сервера', 'max-categories' => 'Количество категорий на пользователя', 'max-feeds' => 'Количество статей на пользователя', + 'cookie-duration' => array( + 'help' => 'in seconds', // @todo translate + 'number' => 'Duration to keep logged in', // @todo translate + ), 'registration' => array( 'help' => '0 означает неограниченное количество пользователей', 'number' => 'Максимальное количество пользователей', @@ -179,15 +183,15 @@ return array( 'user' => array( 'articles_and_size' => '%s статей (%s)', 'create' => 'Создать нового пользователя', - 'delete_users' => 'Delete user', // TODO + 'delete_users' => 'Delete user', //TODO - Translation 'language' => 'Язык', 'number' => 'На данный момент создан %d аккаунт', 'numbers' => 'На данный момент аккаунтов создано: %d', 'password_form' => 'Пароль<br /><small>(для входа через Веб-форму)</small>', 'password_format' => 'Минимум 7 символов', - 'selected' => 'Selected user', // TODO + 'selected' => 'Selected user', //TODO - Translation 'title' => 'Управление пользователями', - 'update_users' => 'Update user', // TODO + 'update_users' => 'Update user', //TODO - Translation 'user_list' => 'Список пользователей', 'username' => 'Имя пользователя', 'users' => 'Пользователи', diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php index b9d45fb20..59ac480bc 100644 --- a/app/i18n/ru/conf.php +++ b/app/i18n/ru/conf.php @@ -6,9 +6,9 @@ return array( 'advanced' => 'Продвинутые настройки', 'delete_after' => 'Удалять статьи после', '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_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' => 'Очистить сейчас', 'title' => 'Архивация', 'ttl' => 'Не обновлять чаще чем', @@ -16,169 +16,172 @@ return array( 'display' => array( '_' => 'Display', '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' => 'Язык', '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' => 'Тема', - 'title' => 'Display', + 'title' => 'Display', //TODO - Translation '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 management', + '_' => 'Profile management', //TODO - Translation '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', - '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( - '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( - '_' => '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 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( - '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', - 'add' => 'Add a sharing method', // TODO + '_' => 'Sharing', //TODO - Translation + 'add' => 'Add a sharing method', //TODO - Translation 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', - 'email' => 'Email', + 'email' => 'Email', //TODO - Translation 'facebook' => 'Facebook', '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', - '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', 'twitter' => 'Twitter', 'wallabag' => 'wallabag', ), '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( - '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 ), ); diff --git a/app/i18n/ru/feedback.php b/app/i18n/ru/feedback.php index 693a40b34..7b859fcdd 100644 --- a/app/i18n/ru/feedback.php +++ b/app/i18n/ru/feedback.php @@ -2,115 +2,115 @@ return array( 'admin' => array( - 'optimization_complete' => 'Optimisation complete', //TODO + 'optimization_complete' => 'Optimisation complete', //TODO - Translation ), '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( '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( - 'invalid' => 'Login is invalid', //TODO - 'success' => 'You are connected', //TODO + 'invalid' => 'Login is invalid', //TODO - Translation + 'success' => 'You are connected', //TODO - Translation ), '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( - '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( - 'already_enabled' => '%s is already enabled', //TODO + 'already_enabled' => '%s is already enabled', //TODO - Translation '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( - '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( - '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( - 'actualize' => 'Actualise', //TODO + 'actualize' => 'Actualise', //TODO - Translation '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( - '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( - '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( - '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( '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( - '_' => '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( - '_' => '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 - ), ); diff --git a/app/i18n/ru/gen.php b/app/i18n/ru/gen.php index 6c8dd2adf..b55c6b667 100644 --- a/app/i18n/ru/gen.php +++ b/app/i18n/ru/gen.php @@ -2,117 +2,117 @@ return 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( - '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', - 'format' => '<small>At least 7 characters</small>', + '_' => 'Password', //TODO - Translation + 'format' => '<small>At least 7 characters</small>', //TODO - Translation ), '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', - '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( - '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', - 'about' => 'About FreshRSS', + '_' => 'FreshRSS', //TODO - Translation + 'about' => 'About FreshRSS', //TODO - Translation ), '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( - '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( 'cz' => 'Čeština', @@ -124,43 +124,43 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', 'zh-cn' => '简体中文', ), '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( - '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( - 'Known' => 'Known based sites', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Known based sites', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Print', 'shaarli' => 'Shaarli', @@ -179,16 +181,16 @@ return array( 'wallabagv2' => 'wallabag v2', ), '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 ), ); diff --git a/app/i18n/ru/index.php b/app/i18n/ru/index.php index aaf25a3ab..977777178 100644 --- a/app/i18n/ru/index.php +++ b/app/i18n/ru/index.php @@ -2,32 +2,32 @@ return 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( - '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( '_' => '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( 'about' => 'About FreshRSS', @@ -40,23 +40,24 @@ return array( 'mark_all_read' => 'Mark all as read', 'mark_cat_read' => 'Mark category 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', - 'unread' => 'Show only unread', + 'tags' => 'My labels', //TODO - Translation + 'unread' => 'Show only unread', //TODO - Translation ), 'share' => 'Share', 'tag' => array( - 'related' => 'Article tags', //TODO + 'related' => 'Article tags', //TODO - Translation ), ); diff --git a/app/i18n/ru/install.php b/app/i18n/ru/install.php index c1d0e81e8..fd1e5c962 100644 --- a/app/i18n/ru/install.php +++ b/app/i18n/ru/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'Конфигурация базы данных сохранена.', ), 'host' => 'Хост', - 'prefix' => 'Префикс таблицы', 'password' => 'Пароль базы данных', + 'prefix' => 'Префикс таблицы', 'type' => 'Тип базы данных', 'username' => 'Имя пользователя базы данных', ), @@ -64,9 +64,13 @@ return array( 'nok' => 'Убедитесь, что вы не изменяете ваш 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( - '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( 'nok' => 'У вас не установлен фрейворк Minz.', @@ -88,6 +92,10 @@ return array( 'nok' => 'Проверьте права доступа к папке <em>./data/users</em> . Сервер HTTP должен иметь права на запись в эту папку.', 'ok' => 'Права на папку users в порядке.', ), + 'xml' => array( + 'nok' => 'Cannot find the required library to parse XML.', + 'ok' => 'You have the required library to parse XML.', + ), ), 'conf' => array( '_' => 'Общие настройки', diff --git a/app/i18n/ru/sub.php b/app/i18n/ru/sub.php index 12901998d..7de80586b 100644 --- a/app/i18n/ru/sub.php +++ b/app/i18n/ru/sub.php @@ -2,85 +2,92 @@ return 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 - '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',// 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( - '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( - '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( - '_' => '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( - '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( - '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( - '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( - '_' => '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 ), ); diff --git a/app/i18n/tr/admin.php b/app/i18n/tr/admin.php index f481bb294..b1d6671ca 100644 --- a/app/i18n/tr/admin.php +++ b/app/i18n/tr/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => 'JSON eklentisi sorunsuz.', ), '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( 'nok' => 'Minz framework eksik.', @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => 'Author', //TODO - Translation + 'community' => 'Available community extensions', //TODO - Translation + 'description' => 'Description', //TODO - Translation 'disabled' => 'Pasif', 'empty_list' => 'Yüklenmiş eklenti bulunmamaktadır', 'enabled' => 'Aktif', + 'latest' => 'Installed', //TODO - Translation + 'name' => 'Name', //TODO - Translation 'no_configure_view' => 'Bu eklenti yapılandırılamaz.', 'system' => array( '_' => 'Sistem eklentileri', 'no_rights' => 'Sistem eklentileri (düzenleme hakkınız yok)', ), 'title' => 'Eklentiler', + 'update' => 'Update available', //TODO - Translation 'user' => 'Kullanıcı eklentileri', - '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( '_' => 'İstatistikler', @@ -162,6 +162,10 @@ return array( 'instance-name' => 'Örnek isim', 'max-categories' => 'Kullanıcı başına kategori limiti', 'max-feeds' => 'Kullanıcı başına akış limiti', + 'cookie-duration' => array( + 'help' => 'in seconds', // @todo translate + 'number' => 'Duration to keep logged in', // @todo translate + ), 'registration' => array( 'help' => '0 sınır yok anlamındadır', 'number' => 'En fazla hesap sayısı', @@ -179,15 +183,15 @@ return array( 'user' => array( 'articles_and_size' => '%s makale (%s)', 'create' => 'Yeni kullanıcı oluştur', - 'delete_users' => 'Delete user', // TODO + 'delete_users' => 'Delete user', //TODO - Translation 'language' => 'Dil', 'number' => 'Oluşturulmuş %d hesap var', 'numbers' => 'Oluşturulmuş %d hesap var', 'password_form' => 'Şifre<br /><small>(Tarayıcı girişi için)</small>', 'password_format' => 'En az 7 karakter', - 'selected' => 'Selected user', // TODO + 'selected' => 'Selected user', //TODO - Translation 'title' => 'Kullanıcıları yönet', - 'update_users' => 'Update user', // TODO + 'update_users' => 'Update user', //TODO - Translation 'user_list' => 'Kullanıcı listesi', 'username' => 'Kullanıcı adı', 'users' => 'Kullanıcılar', diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php index 49533bb6a..507558487 100644 --- a/app/i18n/tr/conf.php +++ b/app/i18n/tr/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => 'Alt çizgi', 'entry' => 'Makale ikonları', 'publication_date' => 'Yayınlama Tarihi', - 'related_tags' => 'İlgili etiketler', //TODO + 'related_tags' => 'İlgili etiketler', //TODO - Translation 'sharing' => 'Paylaşım', 'top_line' => 'Üst çizgi', ), @@ -28,6 +28,7 @@ return array( 'seconds' => 'saniye (0 zaman aşımı yok demektir)', 'timeout' => 'HTML5 bildirim zaman aşımı', ), + 'show_nav_buttons' => 'Show the navigation buttons', //TODO - Translation 'theme' => 'Tema', 'title' => 'Görünüm', 'width' => array( @@ -37,12 +38,22 @@ return array( 'no_limit' => 'Sınırsız', 'thin' => 'Zayıf', ), - 'show_nav_buttons' => 'Show the navigation buttons', //TODO + ), + 'profile' => array( + '_' => 'Profil yönetimi', + 'delete' => array( + '_' => 'Hesap silme', + 'warn' => 'Hesabınız ve tüm verileriniz silinecek.', + ), + 'password_api' => 'API Şifresi<br /><small>(ör. mobil uygulamalar için)</small>', + 'password_form' => 'Şifre<br /><small>(Tarayıcı girişi için)</small>', + 'password_format' => 'En az 7 karakter', + 'title' => 'Profil', ), 'query' => array( '_' => 'Kullanıcı sorguları', 'deprecated' => 'Bu sorgu artık geçerli değil. İlgili akış veya kategori silinmiş.', - 'display' => 'Display user query results', // TODO + 'display' => 'Display user query results', //TODO - Translation 'filter' => 'Filtre uygulandı:', 'get_all' => 'Tüm makaleleri göster', 'get_category' => '"%s" kategorisini göster', @@ -53,7 +64,7 @@ return array( 'number' => 'Sorgu n°%d', 'order_asc' => 'Önce eski makaleleri göster', 'order_desc' => 'Önce yeni makaleleri göster', - 'remove' => 'Remove user query', // TODO + 'remove' => 'Remove user query', //TODO - Translation 'search' => '"%s" için arama', 'state_0' => 'Tüm makaleleri göster', 'state_1' => 'Okunmuş makaleleri göster', @@ -73,31 +84,19 @@ return array( 'state_15' => 'Tüm makaleleri göster', 'title' => 'Kullanıcı sorguları', ), - 'profile' => array( - '_' => 'Profil yönetimi', - 'delete' => array( - '_' => 'Hesap silme', - 'warn' => 'Hesabınız ve tüm verileriniz silinecek.', - ), - 'password_api' => 'API Şifresi<br /><small>(ör. mobil uygulamalar için)</small>', - 'password_form' => 'Şifre<br /><small>(Tarayıcı girişi için)</small>', - 'password_format' => 'En az 7 karakter', - 'title' => 'Profil', - ), 'reading' => array( '_' => 'Okuma', 'after_onread' => '"Hepsini okundu say" dedinten sonra,', 'articles_per_page' => 'Sayfa başına makale sayısı', 'auto_load_more' => 'Sayfa sonunda yeni makaleleri yükle', 'auto_remove_article' => 'Okuduktan sonra makaleleri gizle', - 'mark_updated_article_unread' => 'Güncellenen makaleleri okundu olarak işaretle', 'confirm_enabled' => '"Hepsini okundu say" eylemi için onay iste', 'display_articles_unfolded' => 'Show articles unfolded by default', 'display_categories_unfolded' => 'Show categories folded by default', 'hide_read_feeds' => 'Okunmamış makalesi olmayan kategori veya akışı gizle ("Tüm makaleleri göster" komutunda çalışmaz)', 'img_with_lazyload' => 'Resimleri yüklemek için "tembel modu" kullan', - 'sides_close_article' => 'Clicking outside of article text area closes the article', //TODO 'jump_next' => 'Bir sonraki benzer okunmamışa geç (akış veya kategori)', + 'mark_updated_article_unread' => 'Güncellenen makaleleri okundu olarak işaretle', 'number_divided_when_reader' => 'Okuma modunda ikiye bölünecek.', 'read' => array( 'article_open_on_website' => 'orijinal makale sitesi açıldığında', @@ -112,6 +111,7 @@ return array( 'all_articles' => 'Tüm makaleleri göster', 'unread' => 'Sadece okunmamış makaleleri göster', ), + 'sides_close_article' => 'Clicking outside of article text area closes the article', //TODO - Translation 'sort' => array( '_' => 'Sıralama', 'newer_first' => 'Önce yeniler', @@ -128,7 +128,7 @@ return array( ), 'sharing' => array( '_' => 'Paylaşım', - 'add' => 'Add a sharing method', // TODO + 'add' => 'Add a sharing method', //TODO - Translation 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -136,7 +136,7 @@ return array( 'g+' => 'Google+', 'more_information' => 'Daha fazla bilgi', 'print' => 'Yazdır', - 'remove' => 'Remove sharing method', // TODO + 'remove' => 'Remove sharing method', //TODO - Translation 'shaarli' => 'Shaarli', 'share_name' => 'Paylaşım ismi', 'share_url' => 'Paylaşım URL si', @@ -153,27 +153,30 @@ return array( 'collapse_article' => 'Kapat', 'first_article' => 'İlk makaleyi atla', 'focus_search' => 'Arama kutusuna eriş', - 'global_view' => 'Switch to global view', // TODO + 'global_view' => 'Switch to global view', //TODO - Translation 'help' => 'Dokümantasyonu göster', 'javascript' => 'Kısayolları kullanabilmek için JavaScript aktif olmalıdır', 'last_article' => 'Son makaleyi atla', 'load_more' => 'Daha fazla makale yükle', - 'mark_read' => 'Okundu olarak işaretle', 'mark_favorite' => 'Favori olarak işaretle', + 'mark_read' => 'Okundu olarak işaretle', 'navigation' => 'Genel eylemler', 'navigation_help' => '"Shift" tuşu ile kısayollar akışlar için geçerli olur.<br/>"Alt" tuşu ile kısayollar kategoriler için geçerli olur.', + 'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation 'next_article' => 'Sonraki makaleye geç', - 'normal_view' => 'Switch to normal view', // TODO + 'normal_view' => 'Switch to normal view', //TODO - Translation 'other_action' => 'Diğer eylemler', 'previous_article' => 'Önceki makaleye geç', - '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' => 'Orijinal sitede göster', 'shift_for_all_read' => '+ <code>shift</code> tuşu ile tüm makaleler okundu olarak işaretlenir', + 'skip_next_article' => 'Focus next without opening', //TODO - Translation + 'skip_previous_article' => 'Focus previous without opening', //TODO - Translation 'title' => 'Kısayollar', 'user_filter' => 'Kullanıcı filtrelerine eriş', 'user_filter_help' => 'Eğer tek filtre varsa o kullanılır. Yoksa filtrelerin kendi numaralarıyla kullanılır.', - 'views' => 'Views', // TODO + 'views' => 'Views', //TODO - Translation ), 'user' => array( 'articles_and_size' => '%s makale (%s)', diff --git a/app/i18n/tr/feedback.php b/app/i18n/tr/feedback.php index 278abe978..fc1e59bbc 100644 --- a/app/i18n/tr/feedback.php +++ b/app/i18n/tr/feedback.php @@ -50,11 +50,15 @@ return array( 'no_zip_extension' => 'ZIP eklentisi mevcut sunucunuzda yer almıyor.', 'zip_error' => 'ZIP içe aktarımı sırasında hata meydana geldi.', ), + 'profile' => array( + 'error' => 'Profiliniz düzenlenemedi', + 'updated' => 'Profiliniz düzenlendi', + ), 'sub' => array( 'actualize' => 'Güncelleme', '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( 'created' => 'Kategori %s oluşturuldu.', @@ -76,7 +80,7 @@ return array( 'already_subscribed' => '<em>%s</em> için zaten aboneliğiniz bulunmakta', 'deleted' => 'Akış silindi', 'error' => 'Akış güncellenemiyor', - 'internal_problem' => 'RSS akışı eklenemiyor. Detaylar için <a href="%s">FreshRSS log kayıtlarını</a> kontrol edin.', // @todo + 'internal_problem' => 'RSS akışı eklenemiyor. Detaylar için <a href="%s">FreshRSS log kayıtlarını</a> kontrol edin.', //TODO - Translation 'invalid_url' => 'URL <em>%s</em> geçersiz', 'n_actualized' => '%d akışları güncellendi', 'n_entries_deleted' => '%d makaleleri silindi', @@ -105,12 +109,8 @@ return array( 'error' => '%s kullanıcısı silinemedi', ), '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' => 'Profiliniz düzenlenemedi', - 'updated' => 'Profiliniz düzenlendi', - ), ); diff --git a/app/i18n/tr/gen.php b/app/i18n/tr/gen.php index b8dc18c01..a84c39f20 100644 --- a/app/i18n/tr/gen.php +++ b/app/i18n/tr/gen.php @@ -19,7 +19,7 @@ return array( 'see_website' => 'Siteyi gör', 'submit' => 'Onayla', 'truncate' => 'Tüm makaleleri sil', - 'update' => 'Update', // TODO + 'update' => 'Update', //TODO - Translation ), 'auth' => array( 'email' => 'Email adresleri', @@ -44,33 +44,28 @@ return array( ), 'date' => array( 'Apr' => '\\N\\i\\s\\a\\n', - 'Aug' => '\\A\\ğ\\u\\s\\t\\o\\s', - 'Dec' => '\\A\\r\\a\\l\\ı\\k', - 'Feb' => '\\Ş\\u\\b\\a\\t', - 'Jan' => '\\O\\c\\a\\k', - 'Jul' => '\\T\\e\\m\\m\\u\\z', - 'Jun' => '\\H\\a\\z\\i\\r\\a\\n', - 'Mar' => '\\M\\a\\r\\t', - 'May' => '\\M\\a\\y\\ı\\s', - 'Nov' => '\\K\\a\\s\\ı\\m', - 'Oct' => '\\E\\k\\i\\m', - 'Sep' => '\\E\\y\\l\\ü\\l', 'apr' => 'nis', 'april' => 'Nis', + 'Aug' => '\\A\\ğ\\u\\s\\t\\o\\s', 'aug' => 'ağu', 'august' => 'Ağu', 'before_yesterday' => 'Dünden önceki gün', + 'Dec' => '\\A\\r\\a\\l\\ı\\k', 'dec' => 'ara', 'december' => 'Ara', + 'Feb' => '\\Ş\\u\\b\\a\\t', 'feb' => 'şub', 'february' => 'Şub', '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' => 'Cum', + 'Jan' => '\\O\\c\\a\\k', 'jan' => 'oca', 'january' => 'Oca', + 'Jul' => '\\T\\e\\m\\m\\u\\z', 'jul' => 'tem', 'july' => 'Tem', + 'Jun' => '\\H\\a\\z\\i\\r\\a\\n', 'jun' => 'haz', 'june' => 'Haz', 'last_3_month' => 'Son 3 ay', @@ -78,17 +73,22 @@ return array( 'last_month' => 'Geçen ay', 'last_week' => 'Geçen hafta', 'last_year' => 'Geçen yıl', + 'Mar' => '\\M\\a\\r\\t', 'mar' => 'mar', 'march' => 'Mar', + 'May' => '\\M\\a\\y\\ı\\s', 'may' => 'Mayıs', 'may_' => 'May', 'mon' => 'Pzt', 'month' => 'ay', + 'Nov' => '\\K\\a\\s\\ı\\m', 'nov' => 'kas', 'november' => 'Kas', + 'Oct' => '\\E\\k\\i\\m', 'oct' => 'ekm', 'october' => 'Ekm', 'sat' => 'Cts', + 'Sep' => '\\E\\y\\l\\ü\\l', 'sep' => 'eyl', 'september' => 'Eyl', 'sun' => 'Pzr', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -160,7 +161,6 @@ return array( 'previous' => 'Önceki', ), 'share' => array( - 'Known' => 'Known based sites', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => 'Known based sites', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => 'Print', 'shaarli' => 'Shaarli', diff --git a/app/i18n/tr/index.php b/app/i18n/tr/index.php index e7db73b96..d6db514dd 100644 --- a/app/i18n/tr/index.php +++ b/app/i18n/tr/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => 'Hepsini okundu olarak işaretle', 'mark_cat_read' => 'Kategoriyi okundu olarak işaretle', 'mark_feed_read' => 'Akışı okundu olarak işaretle', - 'mark_selection_unread' => 'Mark selection as unread', //TODO + 'mark_selection_unread' => 'Mark selection as unread', //TODO - Translation 'newer_first' => 'Önce yeniler', 'non-starred' => 'Favori dışındakileri göster', 'normal_view' => 'Normal görünüm', @@ -53,11 +53,11 @@ return array( 'starred' => 'Favorileri göster', 'stats' => 'İstatistikler', 'subscription' => 'Abonelik yönetimi', - 'tags' => 'My labels', //TODO + 'tags' => 'My labels', //TODO - Translation 'unread' => 'Okunmamışları göster', ), 'share' => 'Share', 'tag' => array( - 'related' => 'İlgili etiketler', //TODO + 'related' => 'İlgili etiketler', //TODO - Translation ), ); diff --git a/app/i18n/tr/install.php b/app/i18n/tr/install.php index f90e43f1d..8d152322c 100644 --- a/app/i18n/tr/install.php +++ b/app/i18n/tr/install.php @@ -24,8 +24,8 @@ return array( 'ok' => 'Veritabanı yapılandırılması kayıt edildi.', ), 'host' => 'Sunucu', - 'prefix' => 'Tablo ön eki', 'password' => 'Veritabanı şifresi', + 'prefix' => 'Tablo ön eki', 'type' => 'Veritabanı türü', 'username' => 'Veritabanı kullanıcı adı', ), @@ -69,8 +69,8 @@ return array( 'ok' => 'Tavsiye edilen JSON çözümleme kütüphanesi sorunsuz.', ), '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( 'nok' => 'Minz framework eksik.', diff --git a/app/i18n/tr/sub.php b/app/i18n/tr/sub.php index ef0c8ffbd..b5b56f4b8 100644 --- a/app/i18n/tr/sub.php +++ b/app/i18n/tr/sub.php @@ -2,13 +2,13 @@ return 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 - '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( '_' => 'Kategori', @@ -27,7 +27,7 @@ return array( 'password' => 'HTTP şifre', 'username' => 'HTTP kullanıcı adı', ), - 'clear_cache' => 'Always clear cache', //TODO + 'clear_cache' => 'Always clear cache', //TODO - Translation 'css_help' => 'Dikkat, daha çok zaman gerekir!', 'css_path' => 'Makaleleri kendi CSS görünümü ile göster', 'description' => 'Tanım', @@ -36,30 +36,37 @@ return array( 'informations' => 'Bilgi', 'keep_history' => 'En az tutulacak makale sayısı', 'moved_category_deleted' => 'Bir kategoriyi silerseniz, içerisindeki akışlar <em>%s</em> içerisine yerleşir.', - 'mute' => 'mute', // TODO + 'mute' => 'mute', //TODO - Translation 'no_selected' => 'Hiçbir akış seçilmedi.', 'number_entries' => '%d makale', 'priority' => array( - '_' => 'Visibility', // TODO - 'archived' => 'Do not show (archived)', // TODO + '_' => 'Visibility', //TODO - Translation + 'archived' => 'Do not show (archived)', //TODO - Translation 'main_stream' => 'Ana akışda göster', - 'normal' => 'Show in its category', // TODO + 'normal' => 'Show in its category', //TODO - Translation ), - 'ssl_verify' => 'Verify SSL security', //TODO + 'websub' => 'WebSub ile anlık bildirim', + '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' => 'İstatistikler', 'think_to_add' => 'Akış ekleyebilirsiniz.', - 'timeout' => 'Timeout in seconds', //TODO + 'timeout' => 'Timeout in seconds', //TODO - Translation 'title' => 'Başlık', 'title_add' => 'RSS akışı ekle', 'ttl' => 'Şu kadar süreden fazla otomatik yenileme yapma', 'url' => 'Akış URL', 'validator' => 'Akış geçerliliğini kontrol edin', 'website' => 'Site URL', - 'pubsubhubbub' => 'PubSubHubbub ile anlık bildirim', ), '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( 'export' => 'Dışa aktar', @@ -76,11 +83,11 @@ return array( 'bookmark' => 'Abonelik (FreshRSS yer imleri)', 'import_export' => 'İçe / dışa aktar', 'subscription_management' => 'Abonelik yönetimi', - 'subscription_tools' => 'Subscription tools',// TODO + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), 'title' => array( '_' => 'Abonelik yönetimi', 'feed_management' => 'RSS akış yönetimi', - 'subscription_tools' => 'Subscription tools',// TODO + 'subscription_tools' => 'Subscription tools', //TODO - Translation ), ); diff --git a/app/i18n/zh-cn/admin.php b/app/i18n/zh-cn/admin.php index 1f007f964..e34070526 100644 --- a/app/i18n/zh-cn/admin.php +++ b/app/i18n/zh-cn/admin.php @@ -67,8 +67,8 @@ return array( 'ok' => '已找到 JSON 扩展', ), '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( 'nok' => '找不到 Minz 框架。', @@ -106,23 +106,23 @@ return array( ), ), 'extensions' => array( + 'author' => '作者', + 'community' => '可用的社区扩展', + 'description' => '描述', 'disabled' => '已禁用', 'empty_list' => '没有已安装的扩展', 'enabled' => '已启用', + 'latest' => '已安装', + 'name' => '名称', 'no_configure_view' => '此扩展不能配置。', 'system' => array( '_' => '系统扩展', 'no_rights' => '系统扩展 (你不能修改它)', ), 'title' => '扩展', + 'update' => '更新可用', 'user' => '用户扩展', - 'community' => '可用的社区扩展', - 'name' => '名称', 'version' => '版本', - 'description' => '描述', - 'author' => '作者', - 'latest' => '已安装', - 'update' => '更新可用', ), 'stats' => array( '_' => '统计', @@ -162,6 +162,10 @@ return array( 'instance-name' => '实例名称', 'max-categories' => '每用户分类限制', 'max-feeds' => '每用户 RSS 源限制', + 'cookie-duration' => array( + 'help' => 'in seconds', // @todo translate + 'number' => 'Duration to keep logged in', // @todo translate + ), 'registration' => array( 'help' => '0 表示无账户数限制', 'number' => '最大账户数', @@ -179,15 +183,15 @@ return array( 'user' => array( 'articles_and_size' => '%s 篇文章 (%s)', 'create' => '创建新用户', - 'delete_users' => 'Delete user', // TODO + 'delete_users' => 'Delete user', //TODO - Translation 'language' => '语言', 'number' => '已有 %d 个帐户', 'numbers' => '已有 %d 个帐户', 'password_form' => '密码<br /><small>(用于 Web-form 登录方式)</small>', 'password_format' => '至少 7 个字符', - 'selected' => 'Selected user', // TODO + 'selected' => 'Selected user', //TODO - Translation 'title' => '用户管理', - 'update_users' => 'Update user', // TODO + 'update_users' => 'Update user', //TODO - Translation 'user_list' => '用户列表', 'username' => '用户名', 'users' => '用户', diff --git a/app/i18n/zh-cn/conf.php b/app/i18n/zh-cn/conf.php index 6c62349c2..1216aaaca 100644 --- a/app/i18n/zh-cn/conf.php +++ b/app/i18n/zh-cn/conf.php @@ -19,7 +19,7 @@ return array( 'bottom_line' => '底栏', 'entry' => '文章图标', 'publication_date' => '更新日期', - 'related_tags' => '相关标签', //TODO + 'related_tags' => '相关标签', 'sharing' => '分享', 'top_line' => '顶栏', ), @@ -28,6 +28,7 @@ return array( 'seconds' => '秒 (0 表示不超时)', 'timeout' => 'HTML5 通知超时时间', ), + 'show_nav_buttons' => 'Show the navigation buttons', //TODO - Translation 'theme' => '主题', 'title' => '显示', 'width' => array( @@ -37,12 +38,22 @@ return array( 'no_limit' => '无限制', 'thin' => '小', ), - 'show_nav_buttons' => 'Show the navigation buttons', //TODO + ), + 'profile' => array( + '_' => '帐户管理', + 'delete' => array( + '_' => '账户删除', + 'warn' => '你的帐户和所有相关数据都将被删除。', + ), + 'password_api' => 'API 密码<br /><small>(例如,用于手机 APP)</small>', + 'password_form' => '密码<br /><small>(用于 Web-form 登录方式)</small>', + 'password_format' => '至少 7 个字符', + 'title' => '用户帐户', ), 'query' => array( '_' => '自定义查询', 'deprecated' => '此查询不再有效。相关的分类或 RSS 源已被删除。', - 'display' => 'Display user query results', // TODO + 'display' => 'Display user query results', //TODO - Translation 'filter' => '生效的过滤器:', 'get_all' => '显示所有文章', 'get_category' => '显示分类 "%s"', @@ -53,7 +64,7 @@ return array( 'number' => '查询 n°%d', 'order_asc' => '由旧到新显示文章', 'order_desc' => '由新到旧显示文章', - 'remove' => 'Remove user query', // TODO + 'remove' => 'Remove user query', //TODO - Translation 'search' => '搜索 "%s"', 'state_0' => '显示所有文章', 'state_1' => '显示已读文章', @@ -73,31 +84,19 @@ return array( 'state_15' => '显示所有文章', 'title' => '自定义查询', ), - 'profile' => array( - '_' => '帐户管理', - 'delete' => array( - '_' => '账户删除', - 'warn' => '你的帐户和所有相关数据都将被删除。', - ), - 'password_api' => 'API 密码<br /><small>(例如,用于手机 APP)</small>', - 'password_form' => '密码<br /><small>(用于 Web-form 登录方式)</small>', - 'password_format' => '至少 7 个字符', - 'title' => '用户帐户', - ), 'reading' => array( '_' => '阅读', 'after_onread' => '“全部设为已读”后,', 'articles_per_page' => '每页文章数', 'auto_load_more' => '在页面底部载入下一篇文章', 'auto_remove_article' => '阅读后隐藏文章', - 'mark_updated_article_unread' => '有更新的文章设为未读', 'confirm_enabled' => '“全部设为已读”时显示确认对话框', 'display_articles_unfolded' => '默认展开文章', 'display_categories_unfolded' => '默认展开分类', 'hide_read_feeds' => '隐藏没有未读文章的分类或 RSS 源 (启用“显示所有文章”时不生效))', 'img_with_lazyload' => '延迟加载图片', - 'sides_close_article' => '点击文章外区域以关闭文章', 'jump_next' => '跳转到下一未读项 (RSS 源或分类)', + 'mark_updated_article_unread' => '有更新的文章设为未读', 'number_divided_when_reader' => '阅读视图中显示一半', 'read' => array( 'article_open_on_website' => '在打开原文章后', @@ -112,6 +111,7 @@ return array( 'all_articles' => '显示所有文章', 'unread' => '只显示未读', ), + 'sides_close_article' => '点击文章外区域以关闭文章', 'sort' => array( '_' => '排列顺序', 'newer_first' => '由新到旧', @@ -128,7 +128,7 @@ return array( ), 'sharing' => array( '_' => '分享', - 'add' => 'Add a sharing method', // TODO + 'add' => 'Add a sharing method', //TODO - Translation 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -136,7 +136,7 @@ return array( 'g+' => 'Google+', 'more_information' => '更多信息', 'print' => '打印', - 'remove' => 'Remove sharing method', // TODO + 'remove' => 'Remove sharing method', //TODO - Translation 'shaarli' => 'Shaarli', 'share_name' => '名称', 'share_url' => '地址', @@ -158,10 +158,11 @@ return array( 'javascript' => '若要使用快捷键,必须启用 JavaScript', 'last_article' => '跳转到最后一篇文章', 'load_more' => '载入更多文章', - 'mark_read' => '设为已读', 'mark_favorite' => '加入收藏', + 'mark_read' => '设为已读', 'navigation' => '浏览', 'navigation_help' => '搭配 "Shift" 键,浏览快捷键将生效于 RSS 源。<br/>搭配 "Alt" 键,浏览快捷键将生效于分类。', + 'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation 'next_article' => '跳转到下一篇文章', 'normal_view' => '切换到普通视图', 'other_action' => '其他操作', @@ -170,6 +171,8 @@ return array( 'rss_view' => '在新标签中打开 RSS 视图', 'see_on_website' => '在原网站上查看', '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' => '快捷键', 'user_filter' => '显示自定义查询', 'user_filter_help' => '如果有多个自定义过滤器,则会按照它们的编号依次访问。', diff --git a/app/i18n/zh-cn/feedback.php b/app/i18n/zh-cn/feedback.php index e9f7b4aac..e1778a9f2 100644 --- a/app/i18n/zh-cn/feedback.php +++ b/app/i18n/zh-cn/feedback.php @@ -50,11 +50,15 @@ return array( 'no_zip_extension' => '服务器未启用 ZIP 扩展。', 'zip_error' => '导入 ZIP 文件时出错', ), + 'profile' => array( + 'error' => '你的帐户修改失败', + 'updated' => '你的帐户已修改', + ), 'sub' => array( 'actualize' => '获取', '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( 'created' => '分类 %s 已创建。', @@ -76,7 +80,7 @@ return array( 'already_subscribed' => '你已订阅 <em>%s</em>', 'deleted' => 'RSS 源已删除', 'error' => 'RSS 源更新失败', - 'internal_problem' => 'RSS 源添加失败。<a href="%s">检查 FreshRSS 日志</a> 查看详情。', // @todo + 'internal_problem' => 'RSS 源添加失败。<a href="%s">检查 FreshRSS 日志</a> 查看详情。', //TODO - Translation 'invalid_url' => 'URL <em>%s</em> 无效', 'n_actualized' => '%d 个 RSS 源已更新', 'n_entries_deleted' => '%d 篇文章已删除', @@ -105,12 +109,8 @@ return array( 'error' => '用户 %s 删除失败', ), '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' => '你的帐户修改失败', - 'updated' => '你的帐户已修改', - ), ); diff --git a/app/i18n/zh-cn/gen.php b/app/i18n/zh-cn/gen.php index 078e1d378..1dcd95233 100644 --- a/app/i18n/zh-cn/gen.php +++ b/app/i18n/zh-cn/gen.php @@ -19,7 +19,7 @@ return array( 'see_website' => '查看网站', 'submit' => '提交', 'truncate' => '删除所有文章', - 'update' => 'Update', // TODO + 'update' => 'Update', //TODO - Translation ), 'auth' => array( 'email' => 'Email 地址', @@ -44,33 +44,28 @@ return array( ), 'date' => array( 'Apr' => '\\四\\月', - 'Aug' => '\\八\\月', - 'Dec' => '\\十\\二\\月', - 'Feb' => '\\二\\月', - 'Jan' => '\\一\\月', - 'Jul' => '\\七\\月', - 'Jun' => '\\六\\月', - 'Mar' => '\\三\\月', - 'May' => '\\五\\月', - 'Nov' => '\\十\\一\\月', - 'Oct' => '\\十\\月', - 'Sep' => '\\九\\月', 'apr' => '四月', 'april' => '四月', + 'Aug' => '\\八\\月', 'aug' => '八月', 'august' => '八月', 'before_yesterday' => '昨天以前', + 'Dec' => '\\十\\二\\月', 'dec' => '十二月', 'december' => '十二月', + 'Feb' => '\\二\\月', 'feb' => '二月', 'february' => '二月', 'format_date' => 'Y\\年n\\月j\\日', 'format_date_hour' => 'Y\\年n\\月j\\日 H\\:i', 'fri' => '周五', + 'Jan' => '\\一\\月', 'jan' => '一月', 'january' => '一月', + 'Jul' => '\\七\\月', 'jul' => '七月', 'july' => '七月', + 'Jun' => '\\六\\月', 'jun' => '六月', 'june' => '六月', 'last_3_month' => '最近三个月', @@ -78,17 +73,22 @@ return array( 'last_month' => '上月', 'last_week' => '上周', 'last_year' => '去年', + 'Mar' => '\\三\\月', 'mar' => '三月', 'march' => '三月', + 'May' => '\\五\\月', 'may' => '五月', 'may_' => '五月', 'mon' => '周一', 'month' => '个月', + 'Nov' => '\\十\\一\\月', 'nov' => '十一月', 'november' => '十一月', + 'Oct' => '\\十\\月', 'oct' => '十月', 'october' => '十月', 'sat' => '周日', + 'Sep' => '\\九\\月', 'sep' => '九月', 'september' => '九月', 'sun' => '周日', @@ -124,6 +124,7 @@ return array( 'it' => 'Italiano', 'kr' => '한국어', 'nl' => 'Nederlands', + 'oc' => 'Occitan', 'pt-br' => 'Português (Brasil)', 'ru' => 'Русский', 'tr' => 'Türkçe', @@ -160,7 +161,6 @@ return array( 'previous' => '上一页', ), 'share' => array( - 'Known' => '基于 Known 的站点', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -168,9 +168,11 @@ return array( 'g+' => 'Google+', 'gnusocial' => 'GNU social', 'jdh' => 'Journal du hacker', + 'Known' => '基于 Known 的站点', 'linkedin' => 'LinkedIn', 'mastodon' => 'Mastodon', 'movim' => 'Movim', + 'pinboard' => 'Pinboard', 'pocket' => 'Pocket', 'print' => '打印', 'shaarli' => 'Shaarli', diff --git a/app/i18n/zh-cn/index.php b/app/i18n/zh-cn/index.php index dd8eafda7..3f6b44701 100644 --- a/app/i18n/zh-cn/index.php +++ b/app/i18n/zh-cn/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => '全部设为已读', 'mark_cat_read' => '此分类设为已读', 'mark_feed_read' => '此源设为已读', - 'mark_selection_unread' => 'Mark selection as unread', //TODO + 'mark_selection_unread' => 'Mark selection as unread', //TODO - Translation 'newer_first' => '由新到旧', 'non-starred' => '显示未收藏', 'normal_view' => '普通视图', @@ -53,11 +53,11 @@ return array( 'starred' => '显示收藏', 'stats' => '统计', 'subscription' => '订阅管理', - 'tags' => 'My labels', //TODO + 'tags' => 'My labels', //TODO - Translation 'unread' => '显示未读', ), 'share' => '分享', 'tag' => array( - 'related' => '相关标签', //TODO + 'related' => '相关标签', //TODO - Translation ), ); diff --git a/app/i18n/zh-cn/install.php b/app/i18n/zh-cn/install.php index fe34a44c0..29647932a 100644 --- a/app/i18n/zh-cn/install.php +++ b/app/i18n/zh-cn/install.php @@ -24,8 +24,8 @@ return array( 'ok' => '数据库配置已保存。', ), 'host' => '主机', - 'prefix' => '表前缀', 'password' => '密码', + 'prefix' => '表前缀', 'type' => '数据库类型', 'username' => '用户名', ), @@ -69,8 +69,8 @@ return array( 'ok' => '已找到推荐的 JSON 解析库。', ), '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( 'nok' => '找不到 Minz 框架。', diff --git a/app/i18n/zh-cn/sub.php b/app/i18n/zh-cn/sub.php index 4980b803a..e1c176bc6 100644 --- a/app/i18n/zh-cn/sub.php +++ b/app/i18n/zh-cn/sub.php @@ -27,7 +27,7 @@ return array( 'password' => 'HTTP 密码', 'username' => 'HTTP 用户名', ), - 'clear_cache' => 'Always clear cache', //TODO + 'clear_cache' => 'Always clear cache', //TODO - Translation 'css_help' => '用于获取全文(注意,这将耗费更多时间!)', 'css_path' => '原文的 CSS 选择器', 'description' => '描述', @@ -45,17 +45,24 @@ return array( 'main_stream' => '在首页中显示', 'normal' => '在分类中显示', ), - 'ssl_verify' => 'Verify SSL security', //TODO + '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' => 'Verify SSL security', //TODO - Translation 'stats' => '统计', 'think_to_add' => '你可以添加一些 RSS 源。', - 'timeout' => 'Timeout in seconds', //TODO + 'timeout' => 'Timeout in seconds', //TODO - Translation 'title' => '标题', 'title_add' => '添加 RSS 源', 'ttl' => '最小自动更新时间', 'url' => '源 URL', 'validator' => '检查 RSS 源有效性', 'website' => '网站 URL', - 'pubsubhubbub' => 'PubSubHubbub 即时通知', ), 'firefox' => array( 'documentation' => '按照 <a href="https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox#Adding_a_new_feed_reader_manually">这里</a> 描述的步骤可将 FreshRSS 添加到 Firefox 阅读器列表', diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml index ce029cfa0..5efaa54d1 100644 --- a/app/layout/aside_feed.phtml +++ b/app/layout/aside_feed.phtml @@ -1,4 +1,5 @@ <?php + $actual_view = Minz_Request::actionName(); $class = ''; if (FreshRSS_Context::$user_conf->hide_read_feeds && FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_NOT_READ) && @@ -12,8 +13,8 @@ <?php if (FreshRSS_Auth::hasAccess()) { ?> <div class="stick configure-feeds no-mobile"> - <a class="btn btn-important" href="<?php echo _url('subscription', 'index'); ?>"><?php echo _t('index.menu.subscription'); ?></a> - <a class="btn btn-important" href="<?php echo _url('importExport', 'index'); ?>"><?php echo _i('import'); ?></a> + <a id="btn-subscription" class="btn btn-important" href="<?php echo _url('subscription', 'index'); ?>"><?php echo _t('index.menu.subscription'); ?></a> + <a id="btn-importExport" class="btn btn-important" href="<?php echo _url('importExport', 'index'); ?>"><?php echo _i('import'); ?></a> </div> <?php } elseif (FreshRSS_Auth::accessNeedsLogin()) { ?> <a href="<?php echo _url('index', 'about'); ?>"><?php echo _t('index.menu.about'); ?></a> @@ -21,16 +22,16 @@ <form id="mark-read-aside" method="post"> <input type="hidden" name="_csrf" value="<?php echo FreshRSS_Auth::csrfToken(); ?>" /> - <ul class="tree"> + <ul id="sidebar" class="tree"> <li class="tree-folder category all<?php echo FreshRSS_Context::isCurrentGet('a') ? ' active' : ''; ?>"> <div class="tree-folder-title"> - <?php echo _i('all'); ?> <a class="title" data-unread="<?php echo format_number(FreshRSS_Context::$total_unread); ?>" href="<?php echo _url('index', 'index'); ?>"><?php echo _t('index.menu.main_stream'); ?></a> + <?php echo _i('all'); ?> <a class="title" data-unread="<?php echo format_number(FreshRSS_Context::$total_unread); ?>" href="<?php echo _url('index', $actual_view); ?>"><?php echo _t('index.menu.main_stream'); ?></a> </div> </li> <li class="tree-folder category favorites<?php echo FreshRSS_Context::isCurrentGet('s') ? ' active' : ''; ?>"> <div class="tree-folder-title"> - <?php echo _i('bookmark'); ?> <a class="title" data-unread="<?php echo format_number(FreshRSS_Context::$total_starred['unread']); ?>" href="<?php echo _url('index', 'index', 'get', 's'); ?>"><?php echo _t('index.menu.favorites', format_number(FreshRSS_Context::$total_starred['all'])); ?></a> + <?php echo _i('bookmark'); ?> <a class="title" data-unread="<?php echo format_number(FreshRSS_Context::$total_starred['unread']); ?>" href="<?php echo _url('index', $actual_view, 'get', 's'); ?>"><?php echo _t('index.menu.favorites', format_number(FreshRSS_Context::$total_starred['all'])); ?></a> </div> </li> @@ -40,7 +41,7 @@ <li class="tree-folder category tags<?php echo $t_active ? ' active' : ''; ?>"> <div class="tree-folder-title"> <a class="dropdown-toggle" href="#"><?php echo _i($t_active ? 'up' : 'down'); ?></a> - <a class="title" data-unread="<?php echo format_number($this->nbUnreadTags); ?>" href="<?php echo _url('index', 'index', 'get', 'T'); ?>"><?php echo _t('index.menu.tags'); ?></a> + <a class="title" data-unread="<?php echo format_number($this->nbUnreadTags); ?>" href="<?php echo _url('index', $actual_view, 'get', 'T'); ?>"><?php echo _t('index.menu.tags'); ?></a> </div> <ul class="tree-folder-items<?php echo $t_active ? ' active' : ''; ?>"> <?php @@ -52,7 +53,7 @@ <a class="dropdown-toggle"><?php echo _i('configure'); ?></a> <?php /* tag_config_template */ ?> </div> - <?php echo FreshRSS_Themes::alt('label'); ?> <a class="item-title" data-unread="<?php echo format_number($tag->nbUnread()); ?>" href="<?php echo _url('index', 'index', 'get', 't_' . $tag->id()); ?>"><?php echo $tag->name(); ?></a> + <?php echo FreshRSS_Themes::alt('label'); ?> <a class="item-title" data-unread="<?php echo format_number($tag->nbUnread()); ?>" href="<?php echo _url('index', $actual_view, 'get', 't_' . $tag->id()); ?>"><?php echo $tag->name(); ?></a> </li> <?php endforeach; ?> </ul> @@ -69,7 +70,7 @@ <li class="tree-folder category<?php echo $c_active ? ' active' : ''; ?>" data-unread="<?php echo $cat->nbNotRead(); ?>"> <div class="tree-folder-title"> <a class="dropdown-toggle" href="#"><?php echo _i($c_show ? 'up' : 'down'); ?></a> - <a class="title<?php echo $cat->hasFeedsWithError() ? ' error' : ''; ?>" data-unread="<?php echo format_number($cat->nbNotRead()); ?>" href="<?php echo _url('index', 'index', 'get', 'c_' . $cat->id()); ?>"><?php echo $cat->name(); ?></a> + <a class="title<?php echo $cat->hasFeedsWithError() ? ' error' : ''; ?>" data-unread="<?php echo format_number($cat->nbNotRead()); ?>" href="<?php echo _url('index', $actual_view, 'get', 'c_' . $cat->id()); ?>"><?php echo $cat->name(); ?></a> </div> <ul class="tree-folder-items<?php echo $c_show ? ' active' : ''; ?>"> @@ -83,7 +84,7 @@ <a class="dropdown-toggle" data-fweb="<?php echo $feed->website(); ?>"><?php echo _i('configure'); ?></a> <?php /* feed_config_template */ ?> </div> - <img class="favicon" src="<?php echo $feed->favicon(); ?>" alt="✇" /> <a class="item-title" data-unread="<?php echo format_number($feed->nbNotRead()); ?>" href="<?php echo _url('index', 'index', 'get', 'f_' . $feed->id()); ?>"><?php echo $feed->name(); ?></a> + <img class="favicon" src="<?php echo $feed->favicon(); ?>" alt="✇" /> <a class="item-title" data-unread="<?php echo format_number($feed->nbNotRead()); ?>" href="<?php echo _url('index', $actual_view, 'get', 'f_' . $feed->id()); ?>"><?php echo $feed->name(); ?></a> </li> <?php } ?> </ul> @@ -92,6 +93,7 @@ } } ?> + <li class="tree-bottom"></li> </ul> </form> </div> @@ -110,7 +112,7 @@ <script id="feed_config_template" type="text/html"> <ul class="dropdown-menu"> <li class="dropdown-close"><a href="#close">❌</a></li> - <li class="item"><a href="<?php echo _url('index', 'index', 'get', 'f_------'); ?>"><?php echo _t('gen.action.filter'); ?></a></li> + <li class="item"><a href="<?php echo _url('index', $actual_view, 'get', 'f_------'); ?>"><?php echo _t('gen.action.filter'); ?></a></li> <?php if (FreshRSS_Auth::hasAccess()) { ?> <li class="item"><a href="<?php echo _url('stats', 'repartition', 'id', '------'); ?>"><?php echo _t('index.menu.stats'); ?></a></li> <?php } ?> diff --git a/app/layout/header.phtml b/app/layout/header.phtml index e75a25efa..6b538851b 100644 --- a/app/layout/header.phtml +++ b/app/layout/header.phtml @@ -3,7 +3,8 @@ if (FreshRSS_Auth::accessNeedsAction()) { ?><ul class="nav nav-head nav-login"><?php if (FreshRSS_Auth::hasAccess()) { - ?><li class="item"><?php echo _i('logout'); ?> <a class="signout" href="<?php echo _url('auth', 'logout'); ?>"><?php echo _t('gen.auth.logout'); ?></a></li><?php + ?><li class="item"><?php echo _i('logout'); ?> <a class="signout" href="<?php echo _url('auth', 'logout'); ?>"><?php + echo _t('gen.auth.logout') . ' (' . htmlspecialchars(Minz_Session::param('currentUser', '_'), ENT_NOQUOTES, 'UTF-8') . ')'; ?></a></li><?php } else { ?><li class="item"><?php echo _i('login'); ?> <a class="signin" href="<?php echo _url('auth', 'login'); ?>"><?php echo _t('gen.auth.login'); ?></a></li><?php } @@ -80,11 +81,13 @@ if (FreshRSS_Auth::accessNeedsAction()) { <li class="item"><a href="<?php echo _url('stats', 'index'); ?>"><?php echo _t('gen.menu.stats'); ?></a></li> <li class="item"><a href="<?php echo _url('index', 'logs'); ?>"><?php echo _t('gen.menu.logs'); ?></a></li> <li class="item"><a href="<?php echo _url('index', 'about'); ?>"><?php echo _t('gen.menu.about'); ?></a></li> - <?php - if (FreshRSS_Auth::accessNeedsAction()) { - ?><li class="separator"></li> - <li class="item"><a class="signout" href="<?php echo _url('auth', 'logout'); ?>"><?php echo _i('logout'), ' ', _t('gen.auth.logout'); ?></a></li><?php - } ?> + <li class="separator"></li> + <?php if (FreshRSS_Auth::accessNeedsAction()): ?> + <li class="item"><a class="signout" href="<?php echo _url('auth', 'logout'); ?>"><?php + echo _i('logout') . ' ' . _t('gen.auth.logout') . ' (' . htmlspecialchars(Minz_Session::param('currentUser', '_'), ENT_NOQUOTES, 'UTF-8') . ')'; ?></a></li> + <?php else: ?> + <li class="item"><span class="signout">(<?php echo htmlspecialchars(Minz_Session::param('currentUser', '_'), ENT_NOQUOTES, 'UTF-8'); ?>)</span></li> + <?php endif; ?> </ul> </div> </div> diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index 88f882db9..4d860a54c 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -1,7 +1,7 @@ <?php $actual_view = Minz_Request::actionName(); ?> <div class="nav_menu"> - <?php if ($actual_view === 'normal') { ?> + <?php if ($actual_view === 'normal' || $actual_view === 'reader' ) { ?> <a class="btn toggle_aside" href="#aside_feed"><?php echo _i('category'); ?></a> <?php } ?> diff --git a/app/shares.php b/app/shares.php index 55deed785..4f7fde3ed 100644 --- a/app/shares.php +++ b/app/shares.php @@ -64,7 +64,7 @@ return array( ), 'movim' => array( 'url' => '~URL~/?share/~LINK~', - 'transform' => array('rawurlencode', 'urlencode'), + 'transform' => array('urlencode'), 'help' => 'https://github.com/edhelas/movim', 'form' => 'advanced', 'method' => 'GET', @@ -137,4 +137,11 @@ return array( 'form' => 'simple', 'method' => 'GET', ), + 'pinboard' => array( + 'url' => 'https://pinboard.in/add?next=same&url=~LINK~&title=~TITLE~', + 'transform' => array('urlencode'), + 'help' => 'https://pinboard.in/api/', + 'form' => 'simple', + 'method' => 'GET', + ), ); diff --git a/app/views/configure/shortcut.phtml b/app/views/configure/shortcut.phtml index 66db6a5d4..70a274edd 100644 --- a/app/views/configure/shortcut.phtml +++ b/app/views/configure/shortcut.phtml @@ -65,6 +65,22 @@ </div> </div> + <p class="alert alert-warn"><?php echo _t('conf.shortcut.navigation_no_mod_help');?></p> + + <div class="form-group"> + <label class="group-name" for="skip_next_entry"><?php echo _t('conf.shortcut.skip_next_article'); ?></label> + <div class="group-controls"> + <input type="text" id="skip_next_entry" name="shortcuts[skip_next_entry]" list="keys" value="<?php echo $s['skip_next_entry']; ?>" data-leave-validation="<?php echo $s['skip_next_entry']; ?>"/> + </div> + </div> + + <div class="form-group"> + <label class="group-name" for="skip_prev_entry"><?php echo _t('conf.shortcut.skip_previous_article'); ?></label> + <div class="group-controls"> + <input type="text" id="skip_prev_entry" name="shortcuts[skip_prev_entry]" list="keys" value="<?php echo $s['skip_prev_entry']; ?>" data-leave-validation="<?php echo $s['skip_prev_entry']; ?>"/> + </div> + </div> + <div class="form-group"> <label class="group-name" for="first_entry"><?php echo _t('conf.shortcut.first_article'); ?></label> <div class="group-controls"> diff --git a/app/views/configure/system.phtml b/app/views/configure/system.phtml index 37b68c991..9af4cc2c9 100644 --- a/app/views/configure/system.phtml +++ b/app/views/configure/system.phtml @@ -51,6 +51,14 @@ <input type="number" id="max-categories" name="max-categories" value="<?php echo FreshRSS_Context::$system_conf->limits['max_categories']; ?>" min="1" data-leave-validation="<?php echo FreshRSS_Context::$system_conf->limits['max_categories']; ?>"/> </div> </div> + + <div class="form-group"> + <label class="group-name" for="cookie-duration"><?php echo _t('admin.system.cookie-duration.number'); ?></label> + <div class="group-controls"> + <input type="number" id="cookie-duration" name="cookie-duration" value="<?php echo FreshRSS_Context::$system_conf->limits['cookie_duration']; ?>" min="0" data-leave-validation="<?php echo FreshRSS_Context::$system_conf->limits['cookie_duration']; ?>"/> + <?php echo _i('help'); ?> <?php echo _t('admin.system.cookie-duration.help'); ?> + </div> + </div> <div class="form-group form-actions"> <div class="group-controls"> diff --git a/app/views/error/index.phtml b/app/views/error/index.phtml index fe3abf8c4..8fd74e8bf 100644 --- a/app/views/error/index.phtml +++ b/app/views/error/index.phtml @@ -2,7 +2,7 @@ <div class="alert alert-error"> <h1 class="alert-head"><?php echo $this->code; ?></h1> <p> - <?php echo $this->errorMessage; ?><br /> + <?php echo htmlspecialchars($this->errorMessage, ENT_NOQUOTES, 'UTF-8'); ?><br /> <a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('gen.action.back_to_rss_feeds'); ?></a> </p> </div> diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index b8958f527..59a2c7ad7 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -16,6 +16,12 @@ $articles = array( echo rtrim(json_encode($articles, $options), " ]}\n\r\t"), "\n"; $first = true; +$tagDAO = FreshRSS_Factory::createTagDao(); +$entryIdsTagNames = $tagDAO->getEntryIdsTagNames($this->entriesRaw); +if ($entryIdsTagNames == false) { + $entryIdsTagNames = array(); +} + foreach ($this->entriesRaw as $entryRaw) { if (empty($entryRaw)) { continue; @@ -32,13 +38,14 @@ foreach ($this->entriesRaw as $entryRaw) { $article = array( 'id' => $entry->guid(), + 'timestampUsec' => '' . $entry->id(), 'categories' => array_values($entry->tags()), 'title' => $entry->title(), - 'author' => $entry->authors(true), //TODO: Make an array like tags? + 'author' => $entry->authors(true), 'published' => $entry->date(true), 'updated' => $entry->date(true), 'alternate' => array(array( - 'href' => $entry->link(), + 'href' => htmlspecialchars_decode($entry->link(), ENT_QUOTES), 'type' => 'text/html', )), 'content' => array( @@ -51,6 +58,13 @@ foreach ($this->entriesRaw as $entryRaw) { 'feedUrl' => $feed == null ? '' : $feed->url(), ) ); + if ($entry->isFavorite()) { + $article['categories'][] = 'user/-/state/com.google/starred'; + } + $tagNames = isset($entryIdsTagNames['e_' . $entry->id()]) ? $entryIdsTagNames['e_' . $entry->id()] : array(); + foreach ($tagNames as $tagName) { + $article['categories'][] = 'user/-/label/' . $tagName; + } $line = json_encode($article, $options); if ($line != '') { diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml index 4dbaacd04..bc90ba456 100644 --- a/app/views/helpers/feed/update.phtml +++ b/app/views/helpers/feed/update.phtml @@ -133,7 +133,7 @@ </div> </div> <div class="form-group"> - <label class="group-name" for="pubsubhubbub"><?php echo _t('sub.feed.pubsubhubbub'); ?></label> + <label class="group-name" for="pubsubhubbub"><?php echo _t('sub.feed.websub'); ?></label> <div class="group-controls"> <label class="checkbox" for="pubsubhubbub"> <input type="checkbox" name="pubsubhubbub" id="pubsubhubbub" disabled="disabled" value="1"<?php echo $this->feed->pubSubHubbubEnabled() ? ' checked="checked"' : ''; ?> /> diff --git a/app/views/helpers/index/normal/entry_bottom.phtml b/app/views/helpers/index/normal/entry_bottom.phtml index 784a41e1f..1f35318e3 100644 --- a/app/views/helpers/index/normal/entry_bottom.phtml +++ b/app/views/helpers/index/normal/entry_bottom.phtml @@ -42,7 +42,7 @@ <a class="dropdown-toggle" href="#dropdown-labels-<?php echo $this->entry->id();?>"><?php echo _t('index.menu.tags'); ?></a> - <ul class="dropdown-menu"> + <ul class="dropdown-menu dropdown-menu-scrollable"> <li class="dropdown-close"><a href="#close">❌</a></li> <!-- Ajax --> </ul> diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index d7b3e4360..a434a04a3 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -26,6 +26,8 @@ echo htmlspecialchars(json_encode(array( 'go_website' => @$s['go_website'], 'prev_entry' => @$s['prev_entry'], 'next_entry' => @$s['next_entry'], + 'skip_prev_entry' => @$s['skip_prev_entry'], + 'skip_next_entry' => @$s['skip_next_entry'], 'first_entry' => @$s['first_entry'], 'last_entry' => @$s['last_entry'], 'collapse_entry' => @$s['collapse_entry'], diff --git a/app/views/index/reader.phtml b/app/views/index/reader.phtml index c15b936ee..1485a1997 100644 --- a/app/views/index/reader.phtml +++ b/app/views/index/reader.phtml @@ -1,4 +1,5 @@ <?php +$this->partial('aside_feed'); $this->partial('nav_menu'); flush(); @@ -11,8 +12,11 @@ if (!empty($this->entries)) { $content_width = FreshRSS_Context::$user_conf->content_width; ?> -<div id="stream" class="reader"><?php - foreach ($this->entries as $item) { +<div id="stream" class="reader"> + <div id="new-article"> + <a href="<?php echo Minz_Url::display(Minz_Request::currentRequest()); ?>"><?php echo _t('gen.js.new_article'); /* TODO: move string in JS*/ ?></a> + </div> + <?php foreach ($this->entries as $item) { $item = Minz_ExtensionManager::callHook('entry_before_display', $item); if (is_null($item)) { continue; diff --git a/app/views/subscription/index.phtml b/app/views/subscription/index.phtml index 41dd8a7df..8b196cb00 100644 --- a/app/views/subscription/index.phtml +++ b/app/views/subscription/index.phtml @@ -52,6 +52,12 @@ <?php echo _t('sub.feed.moved_category_deleted', $this->default_category->name()); ?> </p> + <?php if ($this->onlyFeedsWithError): ?> + <p class="alert alert-warn"> + <?php echo _t('sub.feed.showing.error'); ?> + </p> + <?php endif; ?> + <div class="box"> <div class="box-title"><label for="new-category"><?php echo _t('sub.category.add'); ?></label></div> @@ -122,6 +128,9 @@ <?php if (!empty($feeds)) { ?> <?php foreach ($feeds as $feed) { + if ($this->onlyFeedsWithError && !$feed->inError()) { + continue; + } $error = $feed->inError() ? ' error' : ''; $empty = $feed->nbEntries() == 0 ? ' empty' : ''; ?> @@ -140,6 +149,14 @@ </ul> </div> <?php } ?> + + <ul> + <?php if ($this->onlyFeedsWithError): ?> + <li><a href="<?php echo _url('subscription', 'index'); ?>"><?php echo _t('sub.feed.show.all'); ?></a></li> + <?php else: ?> + <li><a href="<?php echo _url('subscription', 'index', 'error', 1); ?>"><?php echo _t('sub.feed.show.error'); ?></a></li> + <?php endif; ?> + </ul> </div> <?php $class = isset($this->feed) ? ' class="active"' : ''; ?> diff --git a/cli/README.md b/cli/README.md index 148e15be5..9c87c394e 100644 --- a/cli/README.md +++ b/cli/README.md @@ -38,7 +38,7 @@ cd /usr/share/FreshRSS ./cli/do-install.php --default_user admin ( --auth_type form --environment production --base_url https://rss.example.net --language en --title FreshRSS --allow_anonymous --api_enabled --db-type mysql --db-host localhost:3306 --db-user freshrss --db-password dbPassword123 --db-base freshrss --db-prefix freshrss ) # --auth_type can be: 'form' (default), 'http_auth' (using the Web server access control), 'none' (dangerous) # --db-type can be: 'sqlite' (default), 'mysql' (MySQL or MariaDB), 'pgsql' (PostgreSQL) -# --base_url should be a public (routable) URL if possible, and is used for push (PubSubHubbub), for some API functions (e.g. favicons), and external URLs in FreshRSS. +# --base_url should be a public (routable) URL if possible, and is used for push (WebSub), for some API functions (e.g. favicons), and external URLs in FreshRSS. # --environment can be: 'production' (default), 'development' (for additional log messages) # --language can be: 'en' (default), 'fr', or one of the [supported languages](../app/i18n/) # --db-prefix is an optional prefix in front of the names of the tables. We suggest using 'freshrss_' diff --git a/cli/i18n/ignore/oc.php b/cli/i18n/ignore/oc.php new file mode 100644 index 000000000..6413fc5f0 --- /dev/null +++ b/cli/i18n/ignore/oc.php @@ -0,0 +1,56 @@ +<?php + +return array( + 'admin.extensions.title', + 'admin.stats.number_entries', + 'admin.user.articles_and_size', + 'conf.display.width.large', + 'conf.sharing.blogotext', + 'conf.sharing.diaspora', + 'conf.sharing.facebook', + 'conf.sharing.g+', + 'conf.sharing.print', + 'conf.sharing.shaarli', + 'conf.sharing.twitter', + 'conf.sharing.wallabag', + 'conf.shortcut.navigation', + 'conf.user.articles_and_size', + 'gen.freshrss._', + 'gen.lang.cz', + 'gen.lang.de', + 'gen.lang.en', + 'gen.lang.es', + 'gen.lang.fr', + 'gen.lang.it', + 'gen.lang.kr', + 'gen.lang.nl', + 'gen.lang.oc', + 'gen.lang.pt-br', + 'gen.lang.ru', + 'gen.lang.tr', + 'gen.lang.zh-cn', + 'gen.menu.admin', + 'gen.menu.configuration', + 'gen.menu.extensions', + 'gen.menu.logs', + 'gen.share.blogotext', + 'gen.share.diaspora', + 'gen.share.facebook', + 'gen.share.g+', + 'gen.share.movim', + 'gen.share.shaarli', + 'gen.share.twitter', + 'gen.share.wallabag', + 'gen.share.wallabagv2', + 'gen.share.jdh', + 'gen.share.gnusocial', + 'index.about.agpl3', + 'index.about.version', + 'index.log._', + 'index.log.title', + 'install.title', + 'install.this_is_the_end', + 'sub.bookmarklet.title', + 'sub.feed.description', + 'sub.feed.number_entries', +); diff --git a/config-user.default.php b/config-user.default.php index 6aef0dc49..08f3af720 100644 --- a/config-user.default.php +++ b/config-user.default.php @@ -49,6 +49,8 @@ return array ( 'go_website' => 'space', 'next_entry' => 'j', 'prev_entry' => 'k', + 'skip_next_entry' => 'n', + 'skip_prev_entry' => 'p', 'first_entry' => 'home', 'last_entry' => 'end', 'collapse_entry' => 'c', diff --git a/config.default.php b/config.default.php index 5b993f9e5..49f0cf1af 100644 --- a/config.default.php +++ b/config.default.php @@ -12,7 +12,7 @@ return array( 'salt' => '', # Specify address of the FreshRSS instance, - # used when building absolute URLs, e.g. for PubSubHubbub. + # used when building absolute URLs, e.g. for WebSub. # Examples: # https://example.net/FreshRSS/p/ # https://freshrss.example.net/ diff --git a/constants.php b/constants.php index 2740dc63d..1f498b153 100644 --- a/constants.php +++ b/constants.php @@ -2,7 +2,7 @@ //NB: Do not edit; use ./constants.local.php instead. //<Not customisable> -define('FRESHRSS_VERSION', '1.12.0'); +define('FRESHRSS_VERSION', '1.13.0'); define('FRESHRSS_WEBSITE', 'https://freshrss.org'); define('FRESHRSS_WIKI', 'https://freshrss.github.io/FreshRSS/'); diff --git a/docs/en/index.md b/docs/en/index.md index 59cbdc296..1aaa6a586 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -16,9 +16,9 @@ FreshRSS has a lot of features including: - Multi-user, so you can also host for your friends and family - And a lot more! -This documentation is split into four sections: +This documentation is split into different sections: -- [user documentation](users/02_First_steps.md) so you can discover all the power of FreshRSS -- [developer documentation](developers/01_First_steps.md) to guide you in the source code of FreshRSS and to help you if you want to contribute -- [administrator documentation](admins/01_Index.md) to guide you in the source code of FreshRSS and to help you if you want to contribute -- [contributor guidelines](contributing.md) for all of you who want to help improving FreshRSS +* [User documentation](./users/02_First_steps.html), where you can discover all the possibilities offered by FreshRSS +* [Administrator documentation](./admins/01_Index.html) for detailed installation and maintenance related tasks +* [Developer documentation](./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](./contributing.md) for those who want to help improve FreshRSS diff --git a/docs/en/users/03_Main_view.md b/docs/en/users/03_Main_view.md index 57eab192d..53d7131b6 100644 --- a/docs/en/users/03_Main_view.md +++ b/docs/en/users/03_Main_view.md @@ -35,14 +35,14 @@ Here is an example to trigger article update every hour. If you do not have access to the installation server scheduled task, you can still automate the update process. -To do so, you need to create a scheduled task, which need to call a specific URL: https://your.server.net/FreshRSS/p/i/?c=feed&a=actualize (it could be different depending on your installation). Depending on your application authentication method, you need to adapt the scheduled task. +To do so, you need to create a scheduled task, which need to call a specific URL: https://freshrss.example.net/i/?c=feed&a=actualize (it could be different depending on your installation). Depending on your application authentication method, you need to adapt the scheduled task. #### No authentication This is the most straightforward since you have a public instance; there is nothing special to configure: ```cron -0 * * * * curl 'https://your.server.net/FreshRSS/p/i/?c=feed&a=actualize' +0 * * * * curl 'https://freshrss.example.net/i/?c=feed&a=actualize' ``` ### Form authentication @@ -60,16 +60,21 @@ You can also configure an authentication token to grant a special right on the s The scheduled task syntax to use will be the following: ```cron -0 * * * * curl 'https://your.server.net/FreshRSS/p/i/?c=feed&a=actualize&token=my-token' +0 * * * * curl 'https://freshrss.example.net/i/?c=feed&a=actualize&token=my-token' ``` +You can also target a different user by adding their username to the query string, with `&user=insert-username`: + +```cron +0 * * * * curl 'https://freshrss.example.net/i/?c=feed&a=actualize&user=someone&token=my-token' +``` ### HTTP authentication In that case, the syntax in the two previous section are unusable. It means that you need to provide your credentials to the scheduled task. **Note that this method is highly discouraged since it means that your credentials will be in plain sight!** ```cron -0 * * * * curl -u alice:password123 'https://your.server.net/FreshRSS/p/i/?c=feed&a=actualize' +0 * * * * curl -u alice:password123 'https://freshrss.example.net/i/?c=feed&a=actualize' ``` ## Manual update diff --git a/docs/en/users/04_Subscriptions.md b/docs/en/users/04_Subscriptions.md index 0772be4cc..4b40f691a 100644 --- a/docs/en/users/04_Subscriptions.md +++ b/docs/en/users/04_Subscriptions.md @@ -8,7 +8,11 @@ # Use bookmarklet -**TODO** +Bookmarklets are little scripts that you can execute to perform useful or frivolous tasks. FreshRSS offers a bookmarklet for subscribing to newsfeeds. + + 1. Open "Subscriptions management". + 2. Click on "Subscription tools". + 3. Drag the "Subscribe" button to your bookmark toolbar or right click and choose your browser's "Bookmark link" action. # Feed management @@ -16,7 +20,9 @@ # Firefox subscription service -You can manually add your FreshRSS app to the list of Firefox subscription services which will enable you to subscribe to sites which provide a feed link using the Firefox built-in "Subscribe" button. An in-depth process is described in the [official documentation](https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox) but you can use the following steps: +NB: From version 63 and onwards Firefox has removed the ability to add your own subscription services that aren't standalone programs. This makes it impossible to add FreshRSS to the feed preview/subscription page, though this page is set to be removed from version 64 anyway (see [bugzilla](https://bugzilla.mozilla.org/show_bug.cgi?id=1477667)). You can use the bookmarklet mentioned above for an easy way to subscribe to feeds. + +If you're using a version pre-63 you can manually add your FreshRSS app to the list of Firefox subscription services, which enables you to subscribe to sites which provide a feed link using the Firefox built-in "Subscribe" button. An in-depth process is described in the [official documentation](https://developer.mozilla.org/en-US/Firefox/Releases/2/Adding_feed_readers_to_Firefox) but you can use the following steps: 1. Open about:config in Firefox diff --git a/docs/en/users/05_Configuration.md b/docs/en/users/05_Configuration.md index 154cd98b5..225c1e5f9 100644 --- a/docs/en/users/05_Configuration.md +++ b/docs/en/users/05_Configuration.md @@ -9,36 +9,22 @@ the missing bits or add a new language, please check how you can [contribute to There are parts of FreshRSS that are not translated and are not intended to be translated. For now, the logs visible in the application as well as the one generated by automatic update scripts are part of it. -Not all languages are equals regarding completion: - -| Language | Completion | -|----------|-----------:| -| cz | 87.4% | -| de | 88.1% | -| en | 100% | -| es | 88.7% | -| fr | 99.3% | -| he | 69.6% | -| it | 86.4% | -| kr | 96.3% | -| nl | 95.4% | -| pt-br | 87.4% | -| ru | 36.4% | -| tr | 88.1% | -| zh-cn | 99.0% | +Available languages are: cz, de, en, es, fr, he, it, kr, nl, oc, pt-br, ru, tr, zh-cn. ## Theme -In matters of taste and color, there can be no disputes. This is why FreshRSS offers six official themes: +In matters of taste and color, there can be no disputes. This is why FreshRSS offers eight official themes: * *Blue Lagoon* by **Mister aiR** * *Dark* by **AD** * *Flat design* by **Marien Fressinaud** * *Origine* by **Marien Fressinaud** + * *Origine-compact* by **Kevin Papst** * *Pafat* by **Plopoyop** * *Screwdriver* by **Mister aiR** + * *Swage* par **Patrick Crandol** -If none of these are suitable for you, it is always possible to create your own. +If none of these are suitable for you, it is always possible to [create your own](../developers/04_Frontend/02_Design.md). To select a theme, simply scroll through the themes and select one that strikes your fancy. After confirmation, the theme will be applied to the interface. @@ -146,7 +132,7 @@ At the moment, there is no helper to build a user query from here. 1. User control is based on the `.htaccess` file. 2. It is best practice to place the `.htaccess` file in the `./i/` subdirectory so the API and other third party services can work. - 3. If you want to limit all access to registered users only, place the file in the FreshRSS directory itself or in a parent directory. Note that PubsubHubbub and API will not work! + 3. If you want to limit all access to registered users only, place the file in the FreshRSS directory itself or in a parent directory. Note that WebSub and API will not work! 4. Example `.htaccess` file for a user "marie": ``` @@ -175,7 +161,7 @@ More information can be found in the [Apache documentation](http://httpd.apache. ## Advanced -### Retrieve a truncated stream +### Retrieve a truncated stream from within FreshRSS The question comes up regularly, so we will try to clarify here how one can retrieve a truncated RSS feed with FreshRSS. Please note that the process is absolutely not "user friendly", but it works :) @@ -183,7 +169,7 @@ Also know that this way you are generating much more traffic to the originating What is meant by "CSS path of articles on the original site" actually corresponds to the "path" consisting of IDs and classes (which in html, matches the id and class attributes) to retrieve only the interesting part that corresponds to the article. Ideally, this path starts with an id (which is unique to the page). -#### Example 1: Rue89 +#### Example: Rue89 To find this path, you must go to the address of one of the truncated articles (for example http://www.rue89.com/2013/10/15/prof-maths-jai-atteint-lextase-dihn-pedagogie-inversee-246635). You must then look for the "block" of HTML corresponding to the content of the article (in the source code!). @@ -194,3 +180,11 @@ We find here that the block that encompasses only the content of the article is * Rue89: ```#article .content``` * PCINpact: ```#actu_content``` * Lesnumériques: ```article#body div.text.clearfix``` +* Phoronix : ```#main .content``` + +### Retrieve a truncated stream with external tools + +Complimentary tools can be used to retrieve full article content, such as: + +* [RSS-Bridge](https://github.com/RSS-Bridge/rss-bridge) +* [Full-Text RSS](https://bitbucket.org/fivefilters/full-text-rss) diff --git a/docs/en/users/06_Mobile_access.md b/docs/en/users/06_Mobile_access.md index c354f98f0..d1b310db3 100644 --- a/docs/en/users/06_Mobile_access.md +++ b/docs/en/users/06_Mobile_access.md @@ -53,6 +53,8 @@ See the [page about the Fever compatible API](06_Fever_API.md) for another possi * [EasyRSS](https://github.com/Alkarex/EasyRSS) (Open source, [F-Droid](https://f-droid.org/packages/org.freshrss.easyrss/)) * Linux * [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Open source) + * MacOS + * [Vienna RSS](http://www.vienna-rss.com/) (Open source) # Google Reader compatible API diff --git a/docs/fr/contributing.md b/docs/fr/contributing.md index c7ccb4d8a..b74f2e673 100644 --- a/docs/fr/contributing.md +++ b/docs/fr/contributing.md @@ -15,6 +15,6 @@ Vous pouvez notamment regarder [les tickets ouverts avec le tag "Documentation"] ## Contribuer au blog -Vous souhaitez écrire un article à propos des technologies RSS/Atom/PubSubHubbub ou tout simplement nous donner un coup de main à la rédaction d'un billet ? Vous pouvez nous aider ! +Vous souhaitez écrire un article à propos des technologies RSS/Atom/WebSub ou tout simplement nous donner un coup de main à la rédaction d'un billet ? Vous pouvez nous aider ! Pour cela, il suffit de vous rendre sur le dépôt GitHub [FreshRSS/freshrss.org](https://github.com/FreshRSS/freshrss.org) et de nous proposer une « Pull Request ». Les articles de blog doivent se trouver dans le répertoire `./blog` et être écrits en Markdown. diff --git a/docs/fr/index.md b/docs/fr/index.md index d43eaec4e..6a9b27cb2 100644 --- a/docs/fr/index.md +++ b/docs/fr/index.md @@ -1,22 +1,24 @@  -FreshRSS est un agrégateur et lecteur de flux RSS. Il permet de regrouper l'actualité de plusieurs sites différents dans un endroit unique pour que vous puissiez la lire sans devoir aller de site en site. +FreshRSS est un agrégateur et lecteur de flux RSS. Il permet de regrouper l’actualité de plusieurs sites différents dans un endroit unique pour que vous puissiez la lire sans devoir aller de site en site. FreshRSS a été conçu comme un agrégateur puissant et propose des tas de fonctionnalités : - Agrégation des flux RSS et Atom. - Utilisez les favoris pour marquer les articles qui vous ont plu ou que vous souhaitez lire plus tard. - Le système de filtrage et de recherche permettent de cibler exactement les articles que vous souhaitez lire. -- Les statistiques permettent de savoir en un coup d'œil quels sont les sites qui publient le plus, ou à l'inverse, le moins. +- Les statistiques permettent de savoir en un coup d’œil quels sont les sites qui publient le plus, ou à l’inverse, le moins. - Importation / exportation des flux au format OPML. -- Multi-thèmes pour changer l'habillage de FreshRSS. -- « *Responsive design* » : l'application s'adapte aux petits écrans pour emporter FreshRSS dans votre poche. +- Multi-thèmes pour changer l’habillage de FreshRSS. +- « *Responsive design* » : l’application s’adapte aux petits écrans pour emporter FreshRSS dans votre poche. - Multi-utilisateurs pour héberger plusieurs personnes sur une même installation. - API Google Reader pour pouvoir y brancher des applications Android. -- Auto-hébergeable : le code source est libre (AGPL3) et vous pouvez donc l'héberger sur votre propre serveur. -- Et bien d'autres ! +- Auto-hébergeable : le code source est libre (AGPL3) et vous pouvez donc l’héberger sur votre propre serveur. +- Et bien d’autres ! -Cette documentation est partagée en deux parties : +Cette documentation est divisée en plusieurs parties : -- La [documentation utilisateurs](users/02_First_steps.md) pour découvrir plus en profondeur les fonctionnalités de FreshRSS. -- La [documentation développeurs](developers/01_First_steps.md) pour savoir comment contribuer et mieux comprendre le code source de FreshRSS. +* La [documentation utilisateurs](./users/02_First_steps.md) pour découvrir les fonctionnalités de FreshRSS. +* La [documentation administrateurs](./users/01_Installation.md) pour l’installation et la maintenance de FreshRSS. +* La [documentation développeurs](./developers/01_First_steps.md) pour savoir comment contribuer et mieux comprendre le code source de FreshRSS. +* Le [guide de contribution](./contributing.md) pour nous aider à développer FreshRSS. diff --git a/docs/fr/users/03_Main_view.md b/docs/fr/users/03_Main_view.md index af3a5a1db..8382340c5 100644 --- a/docs/fr/users/03_Main_view.md +++ b/docs/fr/users/03_Main_view.md @@ -35,14 +35,20 @@ Ci-dessous vous trouverez un exemple permettant la mise à jour des articles tou Il se peut que vous n’ayez pas accès aux tâches planifiées du serveur hébergeant votre instance de FreshRSS. Il reste une possibilité pour mettre les flux à jour automatiquement. -Pour cela vous devez paramétrer une tâche cron qui devra charger régulièrement une url spécifique : https://votre.serveur.net/FreshRSS/p/i/?c=feed&a=actualize (à adapter selon votre installation). Différents cas de figure peuvent se présenter à vous désormais. +Pour cela vous devez paramétrer une tâche cron qui devra charger régulièrement une url spécifique : https://freshrss.example.net/i/?c=feed&a=actualize (à adapter selon votre installation). Différents cas de figure peuvent se présenter à vous désormais. ##### Aucune authentification C’est le cas le plus simple, puisque votre instance est publique, vous n’avez rien de particulier à préciser : ```cron -0 * * * * curl 'https://votre.serveur.net/FreshRSS/p/i/?c=feed&a=actualize' +0 * * * * curl 'https://freshrss.example.net/i/?c=feed&a=actualize' +``` + +Vous pouvez également choisir un utilisateur différent en ajoutant son nom d'utilisateur à la chaîne de requête, avec `&user=nom-dutilisateur` : + +```cron +0 * * * * curl 'https://freshrss.example.net/i/?c=feed&a=actualize&user=someone&token=my-token' ``` ##### Authentification par formulaire @@ -60,7 +66,7 @@ Vous pouvez aussi configurer un jeton d’authentification pour accorder un droi La tâche cron à utiliser sera de la forme suivante : ```cron -0 * * * * curl 'https://votre.serveur.net/FreshRSS/p/i/?c=feed&a=actualize&token=mon-token' +0 * * * * curl 'https://freshrss.example.net/i/?c=feed&a=actualize&token=mon-token' ``` @@ -69,7 +75,7 @@ La tâche cron à utiliser sera de la forme suivante : Dans ce cas-là, le token et les permissions “anonymes” sont inutilisables et il vous sera nécessaire d’indiquer vos identifiants dans la tâche cron. **Notez que cette solution est grandement déconseillée puisqu’elle implique que vos identifiants seront visibles en clair !** ```cron -0 * * * * curl -u alice:password123 'https://votre.serveur.net/FreshRSS/p/i/?c=feed&a=actualize' +0 * * * * curl -u alice:password123 'https://freshrss.example.net/i/?c=feed&a=actualize' ``` ## Mise à jour manuelle diff --git a/docs/fr/users/04_Subscriptions.md b/docs/fr/users/04_Subscriptions.md index ae4541c29..0f8389462 100644 --- a/docs/fr/users/04_Subscriptions.md +++ b/docs/fr/users/04_Subscriptions.md @@ -6,9 +6,13 @@ **TODO** -# Utiliser le « bookmark » +# Utiliser le « bookmarklet » -**TODO** +Les « bookmarklets » sont de petits scripts que vous pouvez exécuter pour effectuer des tâches utiles ou frivoles. FreshRSS offre un signet ( « bookmark » ) pour s'abonner aux fils de nouvelles. + + 1. Ouvrez "Gestion des abonnements". + 2. Cliquez sur "Outils d'abonnement". + 3. Glissez le bouton "S'abonner" dans la barre d'outils des signets ou cliquez droit et choisissez l'action "Lien vers les signets" de votre navigateur. # Organisation des flux diff --git a/docs/fr/users/05_Configuration.md b/docs/fr/users/05_Configuration.md index 75deff462..b1bda9043 100644 --- a/docs/fr/users/05_Configuration.md +++ b/docs/fr/users/05_Configuration.md @@ -1,21 +1,25 @@ # Personnaliser la vue ##Langue -À l'heure actuelle, FreshRSS est disponible en français et en anglais. Après validation de ce choix, la totalité de l'interface sera affichée dans la langue choisie. +À l'heure actuelle, FreshRSS est disponible en 13 langues. Après validation de ce choix, l'interface sera affichée dans la langue choisie, même si certaines parties de l'interface peuvent ne pas encore avoir été traduites. Si vous voulez aider à la traduction, regardez comment vous pouvez [contribuer au projet](../contributing.md#contribute-to-internationalization-i18n). Il y a des parties de FreshRSS qui ne sont pas traduites et qui n'ont pas vocation à l'être. Pour le moment, les logs visibles dans l'application ainsi que celle générées par le script de mise à jour automatique en font partie. +Les langues disponibles sont : cz, de, en, es, fr, he, it, kr, nl, oc, pt-br, ru, tr, zh-cn. + ##Thème -Les goûts et les couleurs, ça ne se discute pas. C'est pourquoi FreshRSS propose six thèmes officiels : +Les goûts et les couleurs, ça ne se discute pas. C'est pourquoi FreshRSS propose huit thèmes officiels : * *Blue Lagoon* par **Mister aiR** * *Dark* par **AD** * *Flat design* par **Marien Fressinaud** * *Origine* par **Marien Fressinaud** + * *Origine-compact* par **Kevin Papst** * *Pafat* par **Plopoyop** * *Screwdriver* par **Mister aiR** + * *Swage* par **Patrick Crandol** -Si aucun de ceux proposés ne convient, il est toujours possible de créer son propre thème. +Si aucun de ceux proposés ne convient, il est toujours possible de [créer son propre thème](../developers/04_Frontend/02_Design.md). Pour sélectionner un thème, il suffit de faire défiler les thèmes jusqu'à l'apparition du thème choisi. Après validation, le thème sera appliqué à l'interface. @@ -97,7 +101,7 @@ Plus d'informations dans [la documentation d'Apache.](http://httpd.apache.org/do ## Avancé -### Récupérer un flux tronqué +### Récupérer un flux tronqué à partir de FreshRSS La question revient régulièrement, je vais essayer de clarifier ici comment on peut récupérer un flux RSS tronqué avec FreshRSS. Sachez avant tout que la manière de s'y prendre n'est absolument pas "user friendly", mais elle fonctionne :) @@ -116,4 +120,11 @@ On trouve ici que le bloc qui englobe uniquement le contenu de l'article est ``` * Rue89 : ```#article .content``` * PCINpact : ```#actu_content``` * Lesnumériques : ```article#body div.text.clearfix``` +* Phoronix : ```#main .content``` + +### Récupérer un flux tronqué à l'aide d'outils externes + +Des outils complémentaires peuvent être utilisés pour récupérer le contenu complet d'un article, comme : +* [RSS-Bridge](https://github.com/RSS-Bridge/rss-bridge) +* [Full-Text RSS](https://bitbucket.org/fivefilters/full-text-rss) diff --git a/docs/fr/users/06_Mobile_access.md b/docs/fr/users/06_Mobile_access.md index 6981a74a6..6f7d92ade 100644 --- a/docs/fr/users/06_Mobile_access.md +++ b/docs/fr/users/06_Mobile_access.md @@ -67,7 +67,8 @@ Tout client supportant une API de type Google Reader. Sélection : * [EasyRSS](https://github.com/Alkarex/EasyRSS) (Libre, F-Droid) * Linux * [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Libre) - +* MacOS + * [Vienna RSS](http://www.vienna-rss.com/) (Libre) # API compatible Google Reader diff --git a/docs/fr/users/08_PubSubHubbub.md b/docs/fr/users/08_PubSubHubbub.md index 0f2f14794..6e220b25b 100644 --- a/docs/fr/users/08_PubSubHubbub.md +++ b/docs/fr/users/08_PubSubHubbub.md @@ -1,15 +1,24 @@ -# Qu'est-ce que PubSubHubbub ? +# Qu’est-ce que [WebSub](https://www.w3.org/TR/websub/) ? -Derrière ce nom barbare se cache un protocole qui vient compléter Atom et RSS. En effet, le fonctionnement de base de ces deux derniers implique de vérifier à intervalles réguliers s'il existe de nouveaux articles sur les sites suivis. Cela même si le site concerné n'a rien publié depuis la dernière synchronisation. Le protocole PubSubHubbub permet d'éviter des synchronisations inutiles en notifiant en temps réel l'agrégateur de la présence de nouveaux articles. +Derrière ce nom (anciennement [PubSubHubbub](https://github.com/pubsubhubbub/PubSubHubbub)) se cache un protocole qui vient compléter Atom et RSS. +En effet, le fonctionnement de base de ces deux derniers implique de vérifier à intervalles réguliers s’il existe de nouveaux articles sur les sites suivis. +Cela même si le site concerné n’a rien publié depuis la dernière synchronisation. +Le [protocole WebSub](https://www.w3.org/TR/websub/) permet d’éviter des synchronisations inutiles en notifiant en temps réel l’agrégateur de la présence de nouveaux articles. -# Fonctionnement de PubSubHubbub +# Fonctionnement de WebSub -On va retrouver trois notions dans PubSubHubbub : les éditeurs (les sites qui publient du contenu), les abonnés (les agrégateurs de flux RSS) et les hubs. +On va retrouver trois notions dans WebSub : les éditeurs (les sites qui publient du contenu), les abonnés (les agrégateurs de flux RSS) et les hubs. -Lorsqu'un agrégateur s'abonne à un site et récupère son flux RSS, il peut y trouver l'adresse d'un hub. Si c'est le cas — car un site peut ne pas en préciser —, l'agrégateur va s'abonner au hub et non pas à l'éditeur directement. Ainsi, lorsqu'un éditeur va publier du contenu, il va notifier le hub qui va lui-même notifier et envoyer le contenu à tous ses abonnés. +Lorsqu’un agrégateur s’abonne à un site et récupère son flux RSS, il peut y trouver l’adresse d’un hub. +Si c’est le cas — car un site peut ne pas en préciser —, l’agrégateur va s’abonner au hub et non pas à l’éditeur directement. +Ainsi, lorsqu’un éditeur va publier du contenu, il va notifier le hub qui va lui-même notifier et envoyer le contenu à tous ses abonnés. Pour pouvoir être notifié, les abonnés doivent fournir une adresse accessible publiquement sur Internet. -# PubSubHubbub et FreshRSS +# WebSub et FreshRSS -Depuis la version 1.1.2-beta, FreshRSS supporte officiellement PubSubHubbub. Vous pouvez donc recevoir en temps réel les articles des sites qui affichent dans leur flux RSS un « hub ». +Depuis la version 1.1.2-beta, FreshRSS supporte officiellement WebSub. +Vous pouvez donc recevoir en temps réel les articles des sites qui affichent dans leur flux RSS un « hub », +tels [Mastodon](https://joinmastodon.org), [Friendica](https://friendi.ca), WordPress (WordPress.com ou avec [une extension](https://wordpress.org/plugins/pubsubhubbub/)), Blogger, FeedBurner, Slashdot, etc. + +Vous pouvez tester avec http://push-pub.appspot.com. diff --git a/lib/Minz/ActionException.php b/lib/Minz/ActionException.php index f1f70c1bc..311f15086 100644 --- a/lib/Minz/ActionException.php +++ b/lib/Minz/ActionException.php @@ -1,9 +1,7 @@ <?php class Minz_ActionException extends Minz_Exception { public function __construct ($controller_name, $action_name, $code = self::ERROR) { - $message = '`' . $action_name . '` cannot be invoked on `' - . $controller_name . '`'; - + $message = 'Invalid action name for controller ' . $controller_name; parent::__construct ($message, $code); } } diff --git a/lib/Minz/ControllerNotExistException.php b/lib/Minz/ControllerNotExistException.php index 24a09a635..dcdaa94d1 100644 --- a/lib/Minz/ControllerNotExistException.php +++ b/lib/Minz/ControllerNotExistException.php @@ -1,9 +1,7 @@ <?php class Minz_ControllerNotExistException extends Minz_Exception { public function __construct ($controller_name, $code = self::ERROR) { - $message = 'Controller `' . $controller_name - . '` doesn\'t exist'; - + $message = 'Controller not found!'; parent::__construct ($message, $code); } } diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 24e30546f..8b2b610d6 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -118,7 +118,9 @@ class Minz_Request { $https = self::isHttps(); - if (!empty($_SERVER['HTTP_HOST'])) { + if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { + $host = parse_url('http://' . $_SERVER['HTTP_X_FORWARDED_HOST'], PHP_URL_HOST); + } elseif (!empty($_SERVER['HTTP_HOST'])) { //Might contain a port number, and mind IPv6 addresses $host = parse_url('http://' . $_SERVER['HTTP_HOST'], PHP_URL_HOST); } elseif (!empty($_SERVER['SERVER_NAME'])) { @@ -142,6 +144,9 @@ class Minz_Request { } else { $url .= '://' . $host . ($port == 80 ? '' : ':' . $port); } + if (!empty($_SERVER['HTTP_X_FORWARDED_PREFIX'])) { + $url .= rtrim($_SERVER['HTTP_X_FORWARDED_PREFIX'], '/ '); + } if (isset($_SERVER['REQUEST_URI'])) { $path = $_SERVER['REQUEST_URI']; $url .= substr($path, -1) === '/' ? substr($path, 0, -1) : dirname($path); diff --git a/lib/SimplePie/SimplePie.php b/lib/SimplePie/SimplePie.php index b591bcddd..d684c1a2c 100644 --- a/lib/SimplePie/SimplePie.php +++ b/lib/SimplePie/SimplePie.php @@ -33,7 +33,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * @package SimplePie - * @version 1.5 + * @version 1.5.2 * @copyright 2004-2017 Ryan Parman, Geoffrey Sneddon, Ryan McCue * @author Ryan Parman * @author Geoffrey Sneddon @@ -50,7 +50,7 @@ define('SIMPLEPIE_NAME', 'SimplePie'); /** * SimplePie Version */ -define('SIMPLEPIE_VERSION', '1.5'); +define('SIMPLEPIE_VERSION', '1.5.2'); /** * SimplePie Build @@ -822,7 +822,7 @@ class SimplePie } /** - * Set the the default timeout for fetching remote feeds + * Set the default timeout for fetching remote feeds * * This allows you to change the maximum time the feed's server to respond * and send the feed back. @@ -1364,6 +1364,11 @@ class SimplePie } } + // The default sanitize class gets set in the constructor, check if it has + // changed. + if ($this->registry->get_class('Sanitize') !== 'SimplePie_Sanitize') { + $this->sanitize = $this->registry->create('Sanitize'); + } if (method_exists($this->sanitize, 'set_registry')) { $this->sanitize->set_registry($this->registry); @@ -1431,7 +1436,7 @@ class SimplePie $md5 = $this->data['md5']; } } - + // Empty response check if(empty($this->raw_data)){ $this->error = "A feed could not be found at `$this->feed_url`. Empty body."; @@ -1508,7 +1513,7 @@ class SimplePie $this->data = $parser->get_data(); if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE)) { - $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed."; + $this->error = "A feed could not be found at `$this->feed_url`. This does not appear to be a valid RSS or Atom feed."; $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); return false; } @@ -1524,7 +1529,7 @@ class SimplePie // Cache the file if caching is enabled if ($cache && !$cache->save($this)) { - trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); + trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); } return true; } @@ -1694,25 +1699,64 @@ class SimplePie if (!$this->force_feed) { // Check if the supplied URL is a feed, if it isn't, look for it. - $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds)); + $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds, $this->force_fsockopen, $this->curl_options)); if (!$locate->is_feed($file)) { $copyStatusCode = $file->status_code; $copyContentType = $file->headers['content-type']; - // We need to unset this so that if SimplePie::set_file() has been called that object is untouched - unset($file); try { - if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))) + $microformats = false; + if (class_exists('DOMXpath') && function_exists('Mf2\parse')) { + $doc = new DOMDocument(); + @$doc->loadHTML($file->body); + $xpath = new DOMXpath($doc); + // Check for both h-feed and h-entry, as both a feed with no entries + // and a list of entries without an h-feed wrapper are both valid. + $query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '. + 'contains(concat(" ", @class, " "), " h-entry ")]'; + $result = $xpath->query($query); + $microformats = $result->length !== 0; + } + // Now also do feed discovery, but if microformats were found don't + // overwrite the current value of file. + $discovered = $locate->find($this->autodiscovery, + $this->all_discovered_feeds); + if ($microformats) { - $this->error = "A feed could not be found at `$this->feed_url`; the status code is `$copyStatusCode` and content-type is `$copyContentType`"; - $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); - return false; + if ($hub = $locate->get_rel_link('hub')) + { + $self = $locate->get_rel_link('self'); + $this->store_links($file, $hub, $self); + } + // Push the current file onto all_discovered feeds so the user can + // be shown this as one of the options. + if (isset($this->all_discovered_feeds)) { + $this->all_discovered_feeds[] = $file; + } + } + else + { + if ($discovered) + { + $file = $discovered; + } + else + { + // We need to unset this so that if SimplePie::set_file() has + // been called that object is untouched + unset($file); + $this->error = "A feed could not be found at `$this->feed_url`; the status code is `$copyStatusCode` and content-type is `$copyContentType`"; + $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); + return false; + } } } catch (SimplePie_Exception $e) { + // We need to unset this so that if SimplePie::set_file() has been called that object is untouched + unset($file); // This is usually because DOMDocument doesn't exist $this->error = $e->getMessage(); $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine())); @@ -1725,7 +1769,7 @@ class SimplePie $this->data['md5'] = empty($md5) ? $this->cleanMd5($file->body) : $md5; if (!$cache->save($this)) { - trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); + trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); } $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc')); } @@ -1922,7 +1966,7 @@ class SimplePie /** * Get the URL for the feed - * + * * When the 'permanent' mode is enabled, returns the original feed URL, * except in the case of an `HTTP 301 Moved Permanently` status response, * in which case the location of the first redirection is returned. @@ -2156,10 +2200,8 @@ class SimplePie { return $this->get_link(); } - else - { - return $this->subscribe_url(); - } + + return $this->subscribe_url(); } /** @@ -2229,10 +2271,8 @@ class SimplePie { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } - else - { - return null; - } + + return null; } /** @@ -2249,10 +2289,8 @@ class SimplePie { return $categories[$key]; } - else - { - return null; - } + + return null; } /** @@ -2314,10 +2352,8 @@ class SimplePie { return array_unique($categories); } - else - { - return null; - } + + return null; } /** @@ -2334,10 +2370,8 @@ class SimplePie { return $authors[$key]; } - else - { - return null; - } + + return null; } /** @@ -2412,10 +2446,8 @@ class SimplePie { return array_unique($authors); } - else - { - return null; - } + + return null; } /** @@ -2432,10 +2464,8 @@ class SimplePie { return $contributors[$key]; } - else - { - return null; - } + + return null; } /** @@ -2498,10 +2528,8 @@ class SimplePie { return array_unique($contributors); } - else - { - return null; - } + + return null; } /** @@ -2519,10 +2547,8 @@ class SimplePie { return $links[$key]; } - else - { - return null; - } + + return null; } /** @@ -2614,20 +2640,18 @@ class SimplePie } } - if (isset($this->data['links'][$rel])) - { - return $this->data['links'][$rel]; - } - else if (isset($this->data['headers']['link']) && - preg_match('/<([^>]+)>; rel='.preg_quote($rel).'/', - $this->data['headers']['link'], $match)) + if (isset($this->data['headers']['link']) && + preg_match('/<([^>]+)>; rel='.preg_quote($rel).'/', + $this->data['headers']['link'], $match)) { return array($match[1]); } - else + else if (isset($this->data['links'][$rel])) { - return null; + return $this->data['links'][$rel]; } + + return null; } public function get_all_discovered_feeds() @@ -2682,10 +2706,8 @@ class SimplePie { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); } - else - { - return null; - } + + return null; } /** @@ -2718,10 +2740,8 @@ class SimplePie { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } - else - { - return null; - } + + return null; } /** @@ -2762,10 +2782,8 @@ class SimplePie { return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT); } - else - { - return null; - } + + return null; } /** @@ -2791,10 +2809,8 @@ class SimplePie { return (float) $match[1]; } - else - { - return null; - } + + return null; } /** @@ -2823,10 +2839,8 @@ class SimplePie { return (float) $match[2]; } - else - { - return null; - } + + return null; } /** @@ -2860,10 +2874,8 @@ class SimplePie { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } - else - { - return null; - } + + return null; } /** @@ -2903,10 +2915,8 @@ class SimplePie { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); } - else - { - return null; - } + + return null; } @@ -2935,10 +2945,8 @@ class SimplePie { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); } - else - { - return null; - } + + return null; } /** @@ -2961,10 +2969,8 @@ class SimplePie { return 88.0; } - else - { - return null; - } + + return null; } /** @@ -2987,10 +2993,8 @@ class SimplePie { return 31.0; } - else - { - return null; - } + + return null; } /** @@ -3010,10 +3014,8 @@ class SimplePie { return $qty; } - else - { - return ($qty > $max) ? $max : $qty; - } + + return ($qty > $max) ? $max : $qty; } /** @@ -3035,10 +3037,8 @@ class SimplePie { return $items[$key]; } - else - { - return null; - } + + return null; } /** @@ -3133,10 +3133,8 @@ class SimplePie { return array_slice($items, $start); } - else - { - return array_slice($items, $start, $end); - } + + return array_slice($items, $start, $end); } /** @@ -3163,7 +3161,7 @@ class SimplePie if (($url = $this->get_link()) !== null) { - return 'http://g.etfv.co/' . urlencode($url); + return 'https://www.google.com/s2/favicons?domain=' . urlencode($url); } return false; @@ -3259,16 +3257,12 @@ class SimplePie { return array_slice($items, $start); } - else - { - return array_slice($items, $start, $end); - } - } - else - { - trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING); - return array(); + + return array_slice($items, $start, $end); } + + trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING); + return array(); } /** diff --git a/lib/SimplePie/SimplePie/Author.php b/lib/SimplePie/SimplePie/Author.php index e6768ff29..14794cf27 100644 --- a/lib/SimplePie/SimplePie/Author.php +++ b/lib/SimplePie/SimplePie/Author.php @@ -113,10 +113,8 @@ class SimplePie_Author { return $this->name; } - else - { - return null; - } + + return null; } /** @@ -130,10 +128,8 @@ class SimplePie_Author { return $this->link; } - else - { - return null; - } + + return null; } /** @@ -147,10 +143,7 @@ class SimplePie_Author { return $this->email; } - else - { - return null; - } + + return null; } } - diff --git a/lib/SimplePie/SimplePie/Cache/MySQL.php b/lib/SimplePie/SimplePie/Cache/MySQL.php index 8686b6c67..061ed043a 100644 --- a/lib/SimplePie/SimplePie/Cache/MySQL.php +++ b/lib/SimplePie/SimplePie/Cache/MySQL.php @@ -96,7 +96,7 @@ class SimplePie_Cache_MySQL extends SimplePie_Cache_DB 'cache_purge_time' => 2592000 ), ); - + $this->options = SimplePie_Misc::array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location)); // Path is prefixed with a "/" @@ -395,10 +395,8 @@ class SimplePie_Cache_MySQL extends SimplePie_Cache_DB { return $time; } - else - { - return false; - } + + return false; } /** @@ -416,14 +414,8 @@ class SimplePie_Cache_MySQL extends SimplePie_Cache_DB $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `mtime` = :time WHERE `id` = :id'); $query->bindValue(':time', time()); $query->bindValue(':id', $this->id); - if ($query->execute() && $query->rowCount() > 0) - { - return true; - } - else - { - return false; - } + + return $query->execute() && $query->rowCount() > 0; } /** @@ -442,13 +434,7 @@ class SimplePie_Cache_MySQL extends SimplePie_Cache_DB $query->bindValue(':id', $this->id); $query2 = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :id'); $query2->bindValue(':id', $this->id); - if ($query->execute() && $query2->execute()) - { - return true; - } - else - { - return false; - } + + return $query->execute() && $query2->execute(); } } diff --git a/lib/SimplePie/SimplePie/Cache/Redis.php b/lib/SimplePie/SimplePie/Cache/Redis.php index 04d72c79a..dbc88e829 100644 --- a/lib/SimplePie/SimplePie/Cache/Redis.php +++ b/lib/SimplePie/SimplePie/Cache/Redis.php @@ -65,6 +65,12 @@ class SimplePie_Cache_Redis implements SimplePie_Cache_Base { $parsed = SimplePie_Cache::parse_URL($location); $redis = new Redis(); $redis->connect($parsed['host'], $parsed['port']); + if (isset($parsed['pass'])) { + $redis->auth($parsed['pass']); + } + if (isset($parsed['path'])) { + $redis->select((int)substr($parsed['path'], 1)); + } $this->cache = $redis; if (!is_null($options) && is_array($options)) { diff --git a/lib/SimplePie/SimplePie/Caption.php b/lib/SimplePie/SimplePie/Caption.php index abf07de1b..854857603 100644 --- a/lib/SimplePie/SimplePie/Caption.php +++ b/lib/SimplePie/SimplePie/Caption.php @@ -131,10 +131,8 @@ class SimplePie_Caption { return $this->endTime; } - else - { - return null; - } + + return null; } /** @@ -149,10 +147,8 @@ class SimplePie_Caption { return $this->lang; } - else - { - return null; - } + + return null; } /** @@ -166,10 +162,8 @@ class SimplePie_Caption { return $this->startTime; } - else - { - return null; - } + + return null; } /** @@ -183,10 +177,8 @@ class SimplePie_Caption { return $this->text; } - else - { - return null; - } + + return null; } /** @@ -200,10 +192,7 @@ class SimplePie_Caption { return $this->type; } - else - { - return null; - } + + return null; } } - diff --git a/lib/SimplePie/SimplePie/Content/Type/Sniffer.php b/lib/SimplePie/SimplePie/Content/Type/Sniffer.php index 6caf80f33..8962e6d9f 100644 --- a/lib/SimplePie/SimplePie/Content/Type/Sniffer.php +++ b/lib/SimplePie/SimplePie/Content/Type/Sniffer.php @@ -118,10 +118,8 @@ class SimplePie_Content_Type_Sniffer { return $return; } - else - { - return $official; - } + + return $official; } elseif ($official === 'text/html' || $official === 'text/xml' //FreshRSS @@ -129,15 +127,11 @@ class SimplePie_Content_Type_Sniffer { return $this->feed_or_html(); } - else - { - return $official; - } - } - else - { - return $this->unknown(); + + return $official; } + + return $this->unknown(); } /** @@ -158,10 +152,8 @@ class SimplePie_Content_Type_Sniffer { return 'application/octect-stream'; } - else - { - return 'text/plain'; - } + + return 'text/plain'; } /** @@ -207,10 +199,8 @@ class SimplePie_Content_Type_Sniffer { return 'image/vnd.microsoft.icon'; } - else - { - return $this->text_or_binary(); - } + + return $this->text_or_binary(); } /** @@ -241,10 +231,8 @@ class SimplePie_Content_Type_Sniffer { return 'image/vnd.microsoft.icon'; } - else - { - return false; - } + + return false; } /** @@ -328,4 +316,3 @@ class SimplePie_Content_Type_Sniffer return 'text/html'; } } - diff --git a/lib/SimplePie/SimplePie/Copyright.php b/lib/SimplePie/SimplePie/Copyright.php index 3f3d07d3b..a57f323e6 100644 --- a/lib/SimplePie/SimplePie/Copyright.php +++ b/lib/SimplePie/SimplePie/Copyright.php @@ -103,10 +103,8 @@ class SimplePie_Copyright { return $this->url; } - else - { - return null; - } + + return null; } /** @@ -120,10 +118,7 @@ class SimplePie_Copyright { return $this->label; } - else - { - return null; - } + + return null; } } - diff --git a/lib/SimplePie/SimplePie/Credit.php b/lib/SimplePie/SimplePie/Credit.php index 9bad9ef34..064a1b864 100644 --- a/lib/SimplePie/SimplePie/Credit.php +++ b/lib/SimplePie/SimplePie/Credit.php @@ -112,10 +112,8 @@ class SimplePie_Credit { return $this->role; } - else - { - return null; - } + + return null; } /** @@ -129,10 +127,8 @@ class SimplePie_Credit { return $this->scheme; } - else - { - return null; - } + + return null; } /** @@ -146,10 +142,7 @@ class SimplePie_Credit { return $this->name; } - else - { - return null; - } + + return null; } } - diff --git a/lib/SimplePie/SimplePie/Decode/HTML/Entities.php b/lib/SimplePie/SimplePie/Decode/HTML/Entities.php index de3f2cb53..773481a8c 100644 --- a/lib/SimplePie/SimplePie/Decode/HTML/Entities.php +++ b/lib/SimplePie/SimplePie/Decode/HTML/Entities.php @@ -117,10 +117,8 @@ class SimplePie_Decode_HTML_Entities $this->consumed .= $this->data[$this->position]; return $this->data[$this->position++]; } - else - { - return false; - } + + return false; } /** @@ -139,10 +137,8 @@ class SimplePie_Decode_HTML_Entities $this->position += $len; return $data; } - else - { - return false; - } + + return false; } /** @@ -612,4 +608,3 @@ class SimplePie_Decode_HTML_Entities } } } - diff --git a/lib/SimplePie/SimplePie/Enclosure.php b/lib/SimplePie/SimplePie/Enclosure.php index 15060e193..ddbbc3c92 100644 --- a/lib/SimplePie/SimplePie/Enclosure.php +++ b/lib/SimplePie/SimplePie/Enclosure.php @@ -282,10 +282,8 @@ class SimplePie_Enclosure { return $this->bitrate; } - else - { - return null; - } + + return null; } /** @@ -301,10 +299,8 @@ class SimplePie_Enclosure { return $captions[$key]; } - else - { - return null; - } + + return null; } /** @@ -318,10 +314,8 @@ class SimplePie_Enclosure { return $this->captions; } - else - { - return null; - } + + return null; } /** @@ -337,10 +331,8 @@ class SimplePie_Enclosure { return $categories[$key]; } - else - { - return null; - } + + return null; } /** @@ -354,10 +346,8 @@ class SimplePie_Enclosure { return $this->categories; } - else - { - return null; - } + + return null; } /** @@ -371,10 +361,8 @@ class SimplePie_Enclosure { return $this->channels; } - else - { - return null; - } + + return null; } /** @@ -388,10 +376,8 @@ class SimplePie_Enclosure { return $this->copyright; } - else - { - return null; - } + + return null; } /** @@ -407,10 +393,8 @@ class SimplePie_Enclosure { return $credits[$key]; } - else - { - return null; - } + + return null; } /** @@ -424,10 +408,8 @@ class SimplePie_Enclosure { return $this->credits; } - else - { - return null; - } + + return null; } /** @@ -441,10 +423,8 @@ class SimplePie_Enclosure { return $this->description; } - else - { - return null; - } + + return null; } /** @@ -462,15 +442,11 @@ class SimplePie_Enclosure $time = SimplePie_Misc::time_hms($this->duration); return $time; } - else - { - return $this->duration; - } - } - else - { - return null; + + return $this->duration; } + + return null; } /** @@ -484,10 +460,8 @@ class SimplePie_Enclosure { return $this->expression; } - else - { - return 'full'; - } + + return 'full'; } /** @@ -519,10 +493,8 @@ class SimplePie_Enclosure { return $this->framerate; } - else - { - return null; - } + + return null; } /** @@ -549,10 +521,8 @@ class SimplePie_Enclosure { return $hashes[$key]; } - else - { - return null; - } + + return null; } /** @@ -566,10 +536,8 @@ class SimplePie_Enclosure { return $this->hashes; } - else - { - return null; - } + + return null; } /** @@ -583,10 +551,8 @@ class SimplePie_Enclosure { return $this->height; } - else - { - return null; - } + + return null; } /** @@ -601,10 +567,8 @@ class SimplePie_Enclosure { return $this->lang; } - else - { - return null; - } + + return null; } /** @@ -620,10 +584,8 @@ class SimplePie_Enclosure { return $keywords[$key]; } - else - { - return null; - } + + return null; } /** @@ -637,10 +599,8 @@ class SimplePie_Enclosure { return $this->keywords; } - else - { - return null; - } + + return null; } /** @@ -654,10 +614,8 @@ class SimplePie_Enclosure { return $this->length; } - else - { - return null; - } + + return null; } /** @@ -671,10 +629,8 @@ class SimplePie_Enclosure { return urldecode($this->link); } - else - { - return null; - } + + return null; } /** @@ -689,10 +645,8 @@ class SimplePie_Enclosure { return $this->medium; } - else - { - return null; - } + + return null; } /** @@ -707,10 +661,8 @@ class SimplePie_Enclosure { return $this->player; } - else - { - return null; - } + + return null; } /** @@ -726,10 +678,8 @@ class SimplePie_Enclosure { return $ratings[$key]; } - else - { - return null; - } + + return null; } /** @@ -743,10 +693,8 @@ class SimplePie_Enclosure { return $this->ratings; } - else - { - return null; - } + + return null; } /** @@ -762,10 +710,8 @@ class SimplePie_Enclosure { return $restrictions[$key]; } - else - { - return null; - } + + return null; } /** @@ -779,10 +725,8 @@ class SimplePie_Enclosure { return $this->restrictions; } - else - { - return null; - } + + return null; } /** @@ -796,10 +740,8 @@ class SimplePie_Enclosure { return $this->samplingrate; } - else - { - return null; - } + + return null; } /** @@ -814,10 +756,8 @@ class SimplePie_Enclosure { return round($length/1048576, 2); } - else - { - return null; - } + + return null; } /** @@ -833,10 +773,8 @@ class SimplePie_Enclosure { return $thumbnails[$key]; } - else - { - return null; - } + + return null; } /** @@ -850,10 +788,8 @@ class SimplePie_Enclosure { return $this->thumbnails; } - else - { - return null; - } + + return null; } /** @@ -867,10 +803,8 @@ class SimplePie_Enclosure { return $this->title; } - else - { - return null; - } + + return null; } /** @@ -885,10 +819,8 @@ class SimplePie_Enclosure { return $this->type; } - else - { - return null; - } + + return null; } /** @@ -902,10 +834,8 @@ class SimplePie_Enclosure { return $this->width; } - else - { - return null; - } + + return null; } /** @@ -1365,15 +1295,10 @@ class SimplePie_Enclosure { return 'mp3'; } - else - { - return null; - } - } - else - { - return $type; + + return null; } + + return $type; } } - diff --git a/lib/SimplePie/SimplePie/File.php b/lib/SimplePie/SimplePie/File.php index b8a595571..c5c398ee1 100644 --- a/lib/SimplePie/SimplePie/File.php +++ b/lib/SimplePie/SimplePie/File.php @@ -71,7 +71,7 @@ class SimplePie_File { $idn = new idna_convert(); $parsed = SimplePie_Misc::parse_url($url); - $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); + $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], NULL); } $this->url = $url; $this->permanent_url = $url; diff --git a/lib/SimplePie/SimplePie/HTTP/Parser.php b/lib/SimplePie/SimplePie/HTTP/Parser.php index 3899c53fa..7d6188dd1 100644 --- a/lib/SimplePie/SimplePie/HTTP/Parser.php +++ b/lib/SimplePie/SimplePie/HTTP/Parser.php @@ -155,15 +155,13 @@ class SimplePie_HTTP_Parser { return true; } - else - { - $this->http_version = ''; - $this->status_code = ''; - $this->reason = ''; - $this->headers = array(); - $this->body = ''; - return false; - } + + $this->http_version = ''; + $this->status_code = ''; + $this->reason = ''; + $this->headers = array(); + $this->body = ''; + return false; } /** @@ -512,6 +510,9 @@ class SimplePie_HTTP_Parser if (false !== stripos($data, "HTTP/1.0 200 Connection established\r\n\r\n")) { $data = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $data); } + if (false !== stripos($data, "HTTP/1.1 200 Connection established\r\n\r\n")) { + $data = str_ireplace("HTTP/1.1 200 Connection established\r\n\r\n", '', $data); + } return $data; } } diff --git a/lib/SimplePie/SimplePie/IRI.php b/lib/SimplePie/SimplePie/IRI.php index 2b3fbaf07..ffba232b1 100644 --- a/lib/SimplePie/SimplePie/IRI.php +++ b/lib/SimplePie/SimplePie/IRI.php @@ -211,10 +211,8 @@ class SimplePie_IRI { return $this->normalization[$this->scheme][$name]; } - else - { - return $return; - } + + return $return; } /** @@ -225,14 +223,7 @@ class SimplePie_IRI */ public function __isset($name) { - if (method_exists($this, 'get_' . $name) || isset($this->$name)) - { - return true; - } - else - { - return false; - } + return method_exists($this, 'get_' . $name) || isset($this->$name); } /** @@ -356,10 +347,8 @@ class SimplePie_IRI $target->scheme_normalization(); return $target; } - else - { - return false; - } + + return false; } } @@ -396,11 +385,9 @@ class SimplePie_IRI } return $match; } - else - { - // This can occur when a paragraph is accidentally parsed as a URI - return false; - } + + // This can occur when a paragraph is accidentally parsed as a URI + return false; } /** @@ -804,7 +791,7 @@ class SimplePie_IRI public function set_iri($iri, $clear_cache = false) { static $cache; - if ($clear_cache) + if ($clear_cache) { $cache = null; return; @@ -830,30 +817,28 @@ class SimplePie_IRI $return) = $cache[$iri]; return $return; } - else - { - $parsed = $this->parse_iri((string) $iri); - if (!$parsed) - { - return false; - } - $return = $this->set_scheme($parsed['scheme']) - && $this->set_authority($parsed['authority']) - && $this->set_path($parsed['path']) - && $this->set_query($parsed['query']) - && $this->set_fragment($parsed['fragment']); - - $cache[$iri] = array($this->scheme, - $this->iuserinfo, - $this->ihost, - $this->port, - $this->ipath, - $this->iquery, - $this->ifragment, - $return); - return $return; + $parsed = $this->parse_iri((string) $iri); + if (!$parsed) + { + return false; } + + $return = $this->set_scheme($parsed['scheme']) + && $this->set_authority($parsed['authority']) + && $this->set_path($parsed['path']) + && $this->set_query($parsed['query']) + && $this->set_fragment($parsed['fragment']); + + $cache[$iri] = array($this->scheme, + $this->iuserinfo, + $this->ihost, + $this->port, + $this->ipath, + $this->iquery, + $this->ifragment, + $return); + return $return; } /** @@ -915,42 +900,40 @@ class SimplePie_IRI return $return; } + + $remaining = $authority; + if (($iuserinfo_end = strrpos($remaining, '@')) !== false) + { + $iuserinfo = substr($remaining, 0, $iuserinfo_end); + $remaining = substr($remaining, $iuserinfo_end + 1); + } else { - $remaining = $authority; - if (($iuserinfo_end = strrpos($remaining, '@')) !== false) - { - $iuserinfo = substr($remaining, 0, $iuserinfo_end); - $remaining = substr($remaining, $iuserinfo_end + 1); - } - else - { - $iuserinfo = null; - } - if (($port_start = strpos($remaining, ':', strpos($remaining, ']'))) !== false) - { - if (($port = substr($remaining, $port_start + 1)) === false) - { - $port = null; - } - $remaining = substr($remaining, 0, $port_start); - } - else + $iuserinfo = null; + } + if (($port_start = strpos($remaining, ':', strpos($remaining, ']'))) !== false) + { + if (($port = substr($remaining, $port_start + 1)) === false) { $port = null; } + $remaining = substr($remaining, 0, $port_start); + } + else + { + $port = null; + } - $return = $this->set_userinfo($iuserinfo) && - $this->set_host($remaining) && - $this->set_port($port); + $return = $this->set_userinfo($iuserinfo) && + $this->set_host($remaining) && + $this->set_port($port); - $cache[$authority] = array($this->iuserinfo, - $this->ihost, - $this->port, - $return); + $cache[$authority] = array($this->iuserinfo, + $this->ihost, + $this->port, + $return); - return $return; - } + return $return; } /** @@ -1050,11 +1033,9 @@ class SimplePie_IRI $this->scheme_normalization(); return true; } - else - { - $this->port = null; - return false; - } + + $this->port = null; + return false; } /** @@ -1066,7 +1047,7 @@ class SimplePie_IRI public function set_path($ipath, $clear_cache = false) { static $cache; - if ($clear_cache) + if ($clear_cache) { $cache = null; return; @@ -1185,7 +1166,7 @@ class SimplePie_IRI { $iri .= $this->ipath; } - elseif (!empty($this->normalization[$this->scheme]['ipath']) && $iauthority !== null && $iauthority !== '') + elseif (!empty($this->normalization[$this->scheme]['ipath']) && $iauthority !== null && $iauthority !== '') { $iri .= $this->normalization[$this->scheme]['ipath']; } @@ -1229,16 +1210,14 @@ class SimplePie_IRI { $iauthority .= $this->ihost; } - if ($this->port !== null) + if ($this->port !== null && $this->port !== 0) { $iauthority .= ':' . $this->port; } return $iauthority; } - else - { - return null; - } + + return null; } /** @@ -1251,7 +1230,7 @@ class SimplePie_IRI $iauthority = $this->get_iauthority(); if (is_string($iauthority)) return $this->to_uri($iauthority); - else - return $iauthority; + + return $iauthority; } } diff --git a/lib/SimplePie/SimplePie/Item.php b/lib/SimplePie/SimplePie/Item.php index 425538606..9b9c1f5db 100644 --- a/lib/SimplePie/SimplePie/Item.php +++ b/lib/SimplePie/SimplePie/Item.php @@ -147,10 +147,8 @@ class SimplePie_Item { return $this->data['child'][$namespace][$tag]; } - else - { - return null; - } + + return null; } /** @@ -366,10 +364,8 @@ class SimplePie_Item { return $this->get_content(true); } - else - { - return null; - } + + return null; } /** @@ -407,18 +403,16 @@ class SimplePie_Item { return $this->get_description(true); } - else - { - return null; - } + + return null; } - + /** * Get the media:thumbnail of the item * * Uses `<media:thumbnail>` * - * + * * @return array|null */ public function get_thumbnail() @@ -435,7 +429,7 @@ class SimplePie_Item } } return $this->data['thumbnail']; - } + } /** * Get a category for the item @@ -451,10 +445,8 @@ class SimplePie_Item { return $categories[$key]; } - else - { - return null; - } + + return null; } /** @@ -477,15 +469,15 @@ class SimplePie_Item $label = null; if (isset($category['attribs']['']['term'])) { - $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_HTML); + $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); } if (isset($category['attribs']['']['scheme'])) { - $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_HTML); + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); } if (isset($category['attribs']['']['label'])) { - $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_HTML); + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); } $categories[] = $this->registry->create('Category', array($term, $scheme, $label, $type)); } @@ -493,10 +485,10 @@ class SimplePie_Item { // This is really the label, but keep this as the term also for BC. // Label will also work on retrieving because that falls back to term. - $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML); + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); if (isset($category['attribs']['']['domain'])) { - $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_HTML); + $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); } else { @@ -508,21 +500,19 @@ class SimplePie_Item $type = 'subject'; foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, $type) as $category) { - $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null, $type)); + $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null, $type)); } foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, $type) as $category) { - $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null, $type)); + $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null, $type)); } if (!empty($categories)) { return array_unique($categories); } - else - { - return null; - } + + return null; } /** @@ -539,10 +529,8 @@ class SimplePie_Item { return $authors[$key]; } - else - { - return null; - } + + return null; } /** @@ -559,10 +547,8 @@ class SimplePie_Item { return $contributors[$key]; } - else - { - return null; - } + + return null; } /** @@ -571,7 +557,7 @@ class SimplePie_Item * Uses `<atom:contributor>` * * @since 1.1 - * @return array|null List of {@see SimplePie_Author} objects + * @return SimplePie_Author[]|null List of {@see SimplePie_Author} objects */ public function get_contributors() { @@ -625,10 +611,8 @@ class SimplePie_Item { return array_unique($contributors); } - else - { - return null; - } + + return null; } /** @@ -637,7 +621,7 @@ class SimplePie_Item * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>` * * @since Beta 2 - * @return array|null List of {@see SimplePie_Author} objects + * @return SimplePie_Author[]|null List of {@see SimplePie_Author} objects */ public function get_authors() { @@ -649,7 +633,7 @@ class SimplePie_Item $email = null; if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) { - $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML); + $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) { @@ -657,7 +641,7 @@ class SimplePie_Item } if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) { - $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML); + $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } if ($name !== null || $email !== null || $uri !== null) { @@ -671,7 +655,7 @@ class SimplePie_Item $email = null; if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) { - $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML); + $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) { @@ -679,7 +663,7 @@ class SimplePie_Item } if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) { - $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML); + $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } if ($name !== null || $email !== null || $url !== null) { @@ -688,19 +672,19 @@ class SimplePie_Item } if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author')) { - $authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_HTML))); + $authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT))); } foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) { - $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null)); + $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); } foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) { - $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null)); + $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); } foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) { - $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null)); + $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); } if (!empty($authors)) @@ -715,10 +699,8 @@ class SimplePie_Item { return $authors; } - else - { - return null; - } + + return null; } /** @@ -743,10 +725,8 @@ class SimplePie_Item { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } - else - { - return null; - } + + return null; } /** @@ -825,10 +805,8 @@ class SimplePie_Item return date($date_format, $this->data['date']['parsed']); } } - else - { - return null; - } + + return null; } /** @@ -876,10 +854,8 @@ class SimplePie_Item return date($date_format, $this->data['updated']['parsed']); } } - else - { - return null; - } + + return null; } /** @@ -905,10 +881,8 @@ class SimplePie_Item { return strftime($date_format, $date); } - else - { - return null; - } + + return null; } /** @@ -969,10 +943,8 @@ class SimplePie_Item { return $enclosure->get_link(); } - else - { - return null; - } + + return null; } /** @@ -990,10 +962,8 @@ class SimplePie_Item { return $links[$key]; } - else - { - return null; - } + + return null; } /** @@ -1073,10 +1043,8 @@ class SimplePie_Item { return $this->data['links'][$rel]; } - else - { - return null; - } + + return null; } /** @@ -1096,10 +1064,8 @@ class SimplePie_Item { return $enclosures[$key]; } - else - { - return null; - } + + return null; } /** @@ -2896,7 +2862,6 @@ class SimplePie_Item $width = null; $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0])); - $url = $this->feed->sanitize->https_url($url); //FreshRSS if (isset($enclosure[0]['attribs']['']['type'])) { $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); @@ -2923,10 +2888,8 @@ class SimplePie_Item { return $this->data['enclosures']; } - else - { - return null; - } + + return null; } /** @@ -2951,10 +2914,8 @@ class SimplePie_Item { return (float) $match[1]; } - else - { - return null; - } + + return null; } /** @@ -2983,10 +2944,8 @@ class SimplePie_Item { return (float) $match[2]; } - else - { - return null; - } + + return null; } /** @@ -3001,10 +2960,7 @@ class SimplePie_Item { return $this->registry->create('Source', array($this, $return[0])); } - else - { - return null; - } + + return null; } } - diff --git a/lib/SimplePie/SimplePie/Locator.php b/lib/SimplePie/SimplePie/Locator.php index bc314c2cd..3876a2da6 100644 --- a/lib/SimplePie/SimplePie/Locator.php +++ b/lib/SimplePie/SimplePie/Locator.php @@ -62,14 +62,18 @@ class SimplePie_Locator var $base_location = 0; var $checked_feeds = 0; var $max_checked_feeds = 10; + var $force_fsockopen = false; + var $curl_options = array(); protected $registry; - public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10) + public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10, $force_fsockopen = false, $curl_options = array()) { $this->file = $file; $this->useragent = $useragent; $this->timeout = $timeout; $this->max_checked_feeds = $max_checked_feeds; + $this->force_fsockopen = $force_fsockopen; + $this->curl_options = $curl_options; if (class_exists('DOMDocument')) { @@ -154,14 +158,8 @@ class SimplePie_Locator { $mime_types[] = 'text/html'; } - if (in_array($sniffed, $mime_types)) - { - return true; - } - else - { - return false; - } + + return in_array($sniffed, $mime_types); } elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL) { @@ -210,10 +208,8 @@ class SimplePie_Locator { return array_values($feeds); } - else - { - return null; - } + + return null; } protected function search_elements_by_tag($name, &$done, $feeds) @@ -254,7 +250,7 @@ class SimplePie_Locator $headers = array( 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', ); - $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent)); + $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options)); if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed, true)) { $feeds[$href] = $feed; @@ -384,7 +380,7 @@ class SimplePie_Locator $headers = array( 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', ); - $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent)); + $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options)); if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) { return array($feed); @@ -412,7 +408,7 @@ class SimplePie_Locator $headers = array( 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', ); - $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent)); + $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen, $this->curl_options)); if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) { return array($feed); @@ -426,4 +422,3 @@ class SimplePie_Locator return null; } } - diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index 1f338623c..016a60ccc 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -221,10 +221,8 @@ class SimplePie_Misc { return substr_replace($url, 'itpc', 0, 4); } - else - { - return $url; - } + + return $url; } public static function array_merge_recursive($array1, $array2) @@ -238,9 +236,9 @@ class SimplePie_Misc else { $array1[$key] = $value; - } + } } - + return $array1; } @@ -280,10 +278,8 @@ class SimplePie_Misc { return chr($integer); } - else - { - return strtoupper($match[0]); - } + + return strtoupper($match[0]); } /** @@ -347,11 +343,9 @@ class SimplePie_Misc { return $return; } + // If we can't do anything, just fail - else - { - return false; - } + return false; } protected static function change_encoding_mbstring($data, $input, $output) @@ -1862,10 +1856,8 @@ class SimplePie_Misc { return trim($mime); } - else - { - return trim(substr($mime, 0, $pos)); - } + + return trim(substr($mime, 0, $pos)); } public static function atom_03_construct_type($attribs) @@ -1898,10 +1890,8 @@ class SimplePie_Misc return SIMPLEPIE_CONSTRUCT_NONE | $mode; } } - else - { - return SIMPLEPIE_CONSTRUCT_TEXT | $mode; - } + + return SIMPLEPIE_CONSTRUCT_TEXT | $mode; } public static function atom_10_construct_type($attribs) @@ -1960,10 +1950,8 @@ class SimplePie_Misc return SIMPLEPIE_CONSTRUCT_BASE64; } } - else - { - return SIMPLEPIE_CONSTRUCT_TEXT; - } + + return SIMPLEPIE_CONSTRUCT_TEXT; } public static function is_isegment_nz_nc($string) @@ -2020,11 +2008,9 @@ class SimplePie_Misc { return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); } - else - { - // U+FFFD REPLACEMENT CHARACTER - return "\xEF\xBF\xBD"; - } + + // U+FFFD REPLACEMENT CHARACTER + return "\xEF\xBF\xBD"; } /** @@ -2276,4 +2262,3 @@ function embed_wmedia(width, height, link) { return preg_replace('#^(https?://)[^/:@]+:[^/:@]+@#i', '$1', $url); } } - diff --git a/lib/SimplePie/SimplePie/Net/IPv6.php b/lib/SimplePie/SimplePie/Net/IPv6.php index 47658aff2..a054e8be5 100644 --- a/lib/SimplePie/SimplePie/Net/IPv6.php +++ b/lib/SimplePie/SimplePie/Net/IPv6.php @@ -173,10 +173,8 @@ class SimplePie_Net_IPv6 { return implode(':', $ip_parts); } - else - { - return $ip_parts[0]; - } + + return $ip_parts[0]; } /** @@ -200,10 +198,8 @@ class SimplePie_Net_IPv6 $ipv4_part = substr($ip, $pos + 1); return array($ipv6_part, $ipv4_part); } - else - { - return array($ip, ''); - } + + return array($ip, ''); } /** @@ -253,10 +249,8 @@ class SimplePie_Net_IPv6 } return true; } - else - { - return false; - } + + return false; } /** diff --git a/lib/SimplePie/SimplePie/Parse/Date.php b/lib/SimplePie/SimplePie/Parse/Date.php index 1f2156655..b29274c64 100644 --- a/lib/SimplePie/SimplePie/Parse/Date.php +++ b/lib/SimplePie/SimplePie/Parse/Date.php @@ -694,10 +694,8 @@ class SimplePie_Parse_Date return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone; } - else - { - return false; - } + + return false; } /** @@ -848,10 +846,8 @@ class SimplePie_Parse_Date return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone; } - else - { - return false; - } + + return false; } /** @@ -913,10 +909,8 @@ class SimplePie_Parse_Date return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone; } - else - { - return false; - } + + return false; } /** @@ -955,10 +949,8 @@ class SimplePie_Parse_Date $month = $this->month[strtolower($match[2])]; return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]); } - else - { - return false; - } + + return false; } /** @@ -974,10 +966,7 @@ class SimplePie_Parse_Date { return false; } - else - { - return $strtotime; - } + + return $strtotime; } } - diff --git a/lib/SimplePie/SimplePie/Parser.php b/lib/SimplePie/SimplePie/Parser.php index bdcc1a516..f9918334c 100644 --- a/lib/SimplePie/SimplePie/Parser.php +++ b/lib/SimplePie/SimplePie/Parser.php @@ -74,7 +74,7 @@ class SimplePie_Parser $this->registry = $registry; } - public function parse(&$data, $encoding) + public function parse(&$data, $encoding, $url = '') { $xmlEncoding = ''; @@ -193,76 +193,72 @@ class SimplePie_Parser xml_parser_free($xml); return $return; } - else + + libxml_clear_errors(); + $xml = new XMLReader(); + $xml->xml($data); + while (@$xml->read()) { - libxml_clear_errors(); - $xml = new XMLReader(); - $xml->xml($data); - while (@$xml->read()) + switch ($xml->nodeType) { - switch ($xml->nodeType) - { - case constant('XMLReader::END_ELEMENT'): + case constant('XMLReader::END_ELEMENT'): + if ($xml->namespaceURI !== '') + { + $tagName = $xml->namespaceURI . $this->separator . $xml->localName; + } + else + { + $tagName = $xml->localName; + } + $this->tag_close(null, $tagName); + break; + case constant('XMLReader::ELEMENT'): + $empty = $xml->isEmptyElement; + if ($xml->namespaceURI !== '') + { + $tagName = $xml->namespaceURI . $this->separator . $xml->localName; + } + else + { + $tagName = $xml->localName; + } + $attributes = array(); + while ($xml->moveToNextAttribute()) + { if ($xml->namespaceURI !== '') { - $tagName = $xml->namespaceURI . $this->separator . $xml->localName; + $attrName = $xml->namespaceURI . $this->separator . $xml->localName; } else { - $tagName = $xml->localName; + $attrName = $xml->localName; } + $attributes[$attrName] = $xml->value; + } + $this->tag_open(null, $tagName, $attributes); + if ($empty) + { $this->tag_close(null, $tagName); - break; - case constant('XMLReader::ELEMENT'): - $empty = $xml->isEmptyElement; - if ($xml->namespaceURI !== '') - { - $tagName = $xml->namespaceURI . $this->separator . $xml->localName; - } - else - { - $tagName = $xml->localName; - } - $attributes = array(); - while ($xml->moveToNextAttribute()) - { - if ($xml->namespaceURI !== '') - { - $attrName = $xml->namespaceURI . $this->separator . $xml->localName; - } - else - { - $attrName = $xml->localName; - } - $attributes[$attrName] = $xml->value; - } - $this->tag_open(null, $tagName, $attributes); - if ($empty) - { - $this->tag_close(null, $tagName); - } - break; - case constant('XMLReader::TEXT'): + } + break; + case constant('XMLReader::TEXT'): - case constant('XMLReader::CDATA'): - $this->cdata(null, $xml->value); - break; - } - } - if ($error = libxml_get_last_error()) - { - $this->error_code = $error->code; - $this->error_string = $error->message; - $this->current_line = $error->line; - $this->current_column = $error->column; - return false; - } - else - { - return true; + case constant('XMLReader::CDATA'): + $this->cdata(null, $xml->value); + break; } } + if ($error = libxml_get_last_error()) + { + $this->error_code = $error->code; + $this->error_string = $error->message; + $this->current_line = $error->line; + $this->current_column = $error->column; + return false; + } + + return true; } public function get_error_code() @@ -473,7 +469,7 @@ class SimplePie_Parser $h_feed = $mf_item; break; } - // Also look for an h-feed in the children of each top level item. + // Also look for h-feed or h-entry in the children of each top level item. if (!isset($mf_item['children'][0]['type'])) continue; if (in_array('h-feed', $mf_item['children'][0]['type'])) { $h_feed = $mf_item['children'][0]; @@ -482,6 +478,13 @@ class SimplePie_Parser if (in_array('h-card', $mf_item['type'])) $feed_author = $mf_item; break; } + else if (in_array('h-entry', $mf_item['children'][0]['type'])) { + $entries = $mf_item['children']; + // In this case the parent of the h-entry list may be an h-card, so use + // it as the feed_author. + if (in_array('h-card', $mf_item['type'])) $feed_author = $mf_item; + break; + } } if (isset($h_feed['children'])) { $entries = $h_feed['children']; @@ -493,7 +496,7 @@ class SimplePie_Parser $feed_author = $mf['items'][0]['properties']['author'][0]; } } - else { + else if (count($entries) === 0) { $entries = $mf['items']; } for ($i = 0; $i < count($entries); $i++) { @@ -562,18 +565,21 @@ class SimplePie_Parser $photo_list = array(); for ($j = 0; $j < count($entry['properties']['photo']); $j++) { $photo = $entry['properties']['photo'][$j]; - if (strpos($content, $photo) === false) { + if (!empty($photo) && strpos($content, $photo) === false) { $photo_list[] = $photo; } } // When there's more than one photo show the first and use a lightbox. + // Need a permanent, unique name for the image set, but don't have + // anything unique except for the content itself, so use that. $count = count($photo_list); if ($count > 1) { + $image_set_id = preg_replace('/[[:^alnum:]]/', '', $photo_list[0]); $description = '<p>'; for ($j = 0; $j < $count; $j++) { $hidden = $j === 0 ? '' : 'class="hidden" '; $description .= '<a href="'.$photo_list[$j].'" '.$hidden. - 'data-lightbox="image-set-'.$i.'">'. + 'data-lightbox="image-set-'.$image_set_id.'">'. '<img src="'.$photo_list[$j].'"></a>'; } $description .= '<br><b>'.$count.' photos</b></p>'; @@ -591,10 +597,18 @@ class SimplePie_Parser $item['title'] = array(array('data' => $title)); } $description .= $entry['properties']['content'][0]['html']; - if (isset($entry['properties']['in-reply-to'][0]['value'])) { - $in_reply_to = $entry['properties']['in-reply-to'][0]['value']; - $description .= '<p><span class="in-reply-to"></span> '. - '<a href="'.$in_reply_to.'">'.$in_reply_to.'</a><p>'; + if (isset($entry['properties']['in-reply-to'][0])) { + $in_reply_to = ''; + if (is_string($entry['properties']['in-reply-to'][0])) { + $in_reply_to = $entry['properties']['in-reply-to'][0]; + } + else if (isset($entry['properties']['in-reply-to'][0]['value'])) { + $in_reply_to = $entry['properties']['in-reply-to'][0]['value']; + } + if ($in_reply_to !== '') { + $description .= '<p><span class="in-reply-to"></span> '. + '<a href="'.$in_reply_to.'">'.$in_reply_to.'</a><p>'; + } } $item['description'] = array(array('data' => $description)); } @@ -635,7 +649,7 @@ class SimplePie_Parser $image = array(array('child' => array('' => array('url' => array(array('data' => $feed_author['properties']['photo'][0])))))); } - // Use the a name given for the h-feed, or get the title from the html. + // Use the name given for the h-feed, or get the title from the html. if ($feed_title !== '') { $feed_title = array(array('data' => htmlspecialchars($feed_title))); } @@ -661,4 +675,4 @@ class SimplePie_Parser // html is allowed, but the xml specification says they must be declared. return '<!DOCTYPE html [ <!ENTITY nbsp " "> <!ENTITY iexcl "¡"> <!ENTITY cent "¢"> <!ENTITY pound "£"> <!ENTITY curren "¤"> <!ENTITY yen "¥"> <!ENTITY brvbar "¦"> <!ENTITY sect "§"> <!ENTITY uml "¨"> <!ENTITY copy "©"> <!ENTITY ordf "ª"> <!ENTITY laquo "«"> <!ENTITY not "¬"> <!ENTITY shy "­"> <!ENTITY reg "®"> <!ENTITY macr "¯"> <!ENTITY deg "°"> <!ENTITY plusmn "±"> <!ENTITY sup2 "²"> <!ENTITY sup3 "³"> <!ENTITY acute "´"> <!ENTITY micro "µ"> <!ENTITY para "¶"> <!ENTITY middot "·"> <!ENTITY cedil "¸"> <!ENTITY sup1 "¹"> <!ENTITY ordm "º"> <!ENTITY raquo "»"> <!ENTITY frac14 "¼"> <!ENTITY frac12 "½"> <!ENTITY frac34 "¾"> <!ENTITY iquest "¿"> <!ENTITY Agrave "À"> <!ENTITY Aacute "Á"> <!ENTITY Acirc "Â"> <!ENTITY Atilde "Ã"> <!ENTITY Auml "Ä"> <!ENTITY Aring "Å"> <!ENTITY AElig "Æ"> <!ENTITY Ccedil "Ç"> <!ENTITY Egrave "È"> <!ENTITY Eacute "É"> <!ENTITY Ecirc "Ê"> <!ENTITY Euml "Ë"> <!ENTITY Igrave "Ì"> <!ENTITY Iacute "Í"> <!ENTITY Icirc "Î"> <!ENTITY Iuml "Ï"> <!ENTITY ETH "Ð"> <!ENTITY Ntilde "Ñ"> <!ENTITY Ograve "Ò"> <!ENTITY Oacute "Ó"> <!ENTITY Ocirc "Ô"> <!ENTITY Otilde "Õ"> <!ENTITY Ouml "Ö"> <!ENTITY times "×"> <!ENTITY Oslash "Ø"> <!ENTITY Ugrave "Ù"> <!ENTITY Uacute "Ú"> <!ENTITY Ucirc "Û"> <!ENTITY Uuml "Ü"> <!ENTITY Yacute "Ý"> <!ENTITY THORN "Þ"> <!ENTITY szlig "ß"> <!ENTITY agrave "à"> <!ENTITY aacute "á"> <!ENTITY acirc "â"> <!ENTITY atilde "ã"> <!ENTITY auml "ä"> <!ENTITY aring "å"> <!ENTITY aelig "æ"> <!ENTITY ccedil "ç"> <!ENTITY egrave "è"> <!ENTITY eacute "é"> <!ENTITY ecirc "ê"> <!ENTITY euml "ë"> <!ENTITY igrave "ì"> <!ENTITY iacute "í"> <!ENTITY icirc "î"> <!ENTITY iuml "ï"> <!ENTITY eth "ð"> <!ENTITY ntilde "ñ"> <!ENTITY ograve "ò"> <!ENTITY oacute "ó"> <!ENTITY ocirc "ô"> <!ENTITY otilde "õ"> <!ENTITY ouml "ö"> <!ENTITY divide "÷"> <!ENTITY oslash "ø"> <!ENTITY ugrave "ù"> <!ENTITY uacute "ú"> <!ENTITY ucirc "û"> <!ENTITY uuml "ü"> <!ENTITY yacute "ý"> <!ENTITY thorn "þ"> <!ENTITY yuml "ÿ"> <!ENTITY OElig "Œ"> <!ENTITY oelig "œ"> <!ENTITY Scaron "Š"> <!ENTITY scaron "š"> <!ENTITY Yuml "Ÿ"> <!ENTITY fnof "ƒ"> <!ENTITY circ "ˆ"> <!ENTITY tilde "˜"> <!ENTITY Alpha "Α"> <!ENTITY Beta "Β"> <!ENTITY Gamma "Γ"> <!ENTITY Epsilon "Ε"> <!ENTITY Zeta "Ζ"> <!ENTITY Eta "Η"> <!ENTITY Theta "Θ"> <!ENTITY Iota "Ι"> <!ENTITY Kappa "Κ"> <!ENTITY Lambda "Λ"> <!ENTITY Mu "Μ"> <!ENTITY Nu "Ν"> <!ENTITY Xi "Ξ"> <!ENTITY Omicron "Ο"> <!ENTITY Pi "Π"> <!ENTITY Rho "Ρ"> <!ENTITY Sigma "Σ"> <!ENTITY Tau "Τ"> <!ENTITY Upsilon "Υ"> <!ENTITY Phi "Φ"> <!ENTITY Chi "Χ"> <!ENTITY Psi "Ψ"> <!ENTITY Omega "Ω"> <!ENTITY alpha "α"> <!ENTITY beta "β"> <!ENTITY gamma "γ"> <!ENTITY delta "δ"> <!ENTITY epsilon "ε"> <!ENTITY zeta "ζ"> <!ENTITY eta "η"> <!ENTITY theta "θ"> <!ENTITY iota "ι"> <!ENTITY kappa "κ"> <!ENTITY lambda "λ"> <!ENTITY mu "μ"> <!ENTITY nu "ν"> <!ENTITY xi "ξ"> <!ENTITY omicron "ο"> <!ENTITY pi "π"> <!ENTITY rho "ρ"> <!ENTITY sigmaf "ς"> <!ENTITY sigma "σ"> <!ENTITY tau "τ"> <!ENTITY upsilon "υ"> <!ENTITY phi "φ"> <!ENTITY chi "χ"> <!ENTITY psi "ψ"> <!ENTITY omega "ω"> <!ENTITY thetasym "ϑ"> <!ENTITY upsih "ϒ"> <!ENTITY piv "ϖ"> <!ENTITY ensp " "> <!ENTITY emsp " "> <!ENTITY thinsp " "> <!ENTITY zwnj "‌"> <!ENTITY zwj "‍"> <!ENTITY lrm "‎"> <!ENTITY rlm "‏"> <!ENTITY ndash "–"> <!ENTITY mdash "—"> <!ENTITY lsquo "‘"> <!ENTITY rsquo "’"> <!ENTITY sbquo "‚"> <!ENTITY ldquo "“"> <!ENTITY rdquo "”"> <!ENTITY bdquo "„"> <!ENTITY dagger "†"> <!ENTITY Dagger "‡"> <!ENTITY bull "•"> <!ENTITY hellip "…"> <!ENTITY permil "‰"> <!ENTITY prime "′"> <!ENTITY Prime "″"> <!ENTITY lsaquo "‹"> <!ENTITY rsaquo "›"> <!ENTITY oline "‾"> <!ENTITY frasl "⁄"> <!ENTITY euro "€"> <!ENTITY image "ℑ"> <!ENTITY weierp "℘"> <!ENTITY real "ℜ"> <!ENTITY trade "™"> <!ENTITY alefsym "ℵ"> <!ENTITY larr "←"> <!ENTITY uarr "↑"> <!ENTITY rarr "→"> <!ENTITY darr "↓"> <!ENTITY harr "↔"> <!ENTITY crarr "↵"> <!ENTITY lArr "⇐"> <!ENTITY uArr "⇑"> <!ENTITY rArr "⇒"> <!ENTITY dArr "⇓"> <!ENTITY hArr "⇔"> <!ENTITY forall "∀"> <!ENTITY part "∂"> <!ENTITY exist "∃"> <!ENTITY empty "∅"> <!ENTITY nabla "∇"> <!ENTITY isin "∈"> <!ENTITY notin "∉"> <!ENTITY ni "∋"> <!ENTITY prod "∏"> <!ENTITY sum "∑"> <!ENTITY minus "−"> <!ENTITY lowast "∗"> <!ENTITY radic "√"> <!ENTITY prop "∝"> <!ENTITY infin "∞"> <!ENTITY ang "∠"> <!ENTITY and "∧"> <!ENTITY or "∨"> <!ENTITY cap "∩"> <!ENTITY cup "∪"> <!ENTITY int "∫"> <!ENTITY there4 "∴"> <!ENTITY sim "∼"> <!ENTITY cong "≅"> <!ENTITY asymp "≈"> <!ENTITY ne "≠"> <!ENTITY equiv "≡"> <!ENTITY le "≤"> <!ENTITY ge "≥"> <!ENTITY sub "⊂"> <!ENTITY sup "⊃"> <!ENTITY nsub "⊄"> <!ENTITY sube "⊆"> <!ENTITY supe "⊇"> <!ENTITY oplus "⊕"> <!ENTITY otimes "⊗"> <!ENTITY perp "⊥"> <!ENTITY sdot "⋅"> <!ENTITY lceil "⌈"> <!ENTITY rceil "⌉"> <!ENTITY lfloor "⌊"> <!ENTITY rfloor "⌋"> <!ENTITY lang "〈"> <!ENTITY rang "〉"> <!ENTITY loz "◊"> <!ENTITY spades "♠"> <!ENTITY clubs "♣"> <!ENTITY hearts "♥"> <!ENTITY diams "♦"> ]>'; } -}
\ No newline at end of file +} diff --git a/lib/SimplePie/SimplePie/Rating.php b/lib/SimplePie/SimplePie/Rating.php index eaf57080c..108dd22bf 100644 --- a/lib/SimplePie/SimplePie/Rating.php +++ b/lib/SimplePie/SimplePie/Rating.php @@ -103,10 +103,8 @@ class SimplePie_Rating { return $this->scheme; } - else - { - return null; - } + + return null; } /** @@ -120,9 +118,7 @@ class SimplePie_Rating { return $this->value; } - else - { - return null; - } + + return null; } } diff --git a/lib/SimplePie/SimplePie/Restriction.php b/lib/SimplePie/SimplePie/Restriction.php index 001a5cd28..803d84fde 100644 --- a/lib/SimplePie/SimplePie/Restriction.php +++ b/lib/SimplePie/SimplePie/Restriction.php @@ -112,10 +112,8 @@ class SimplePie_Restriction { return $this->relationship; } - else - { - return null; - } + + return null; } /** @@ -129,10 +127,8 @@ class SimplePie_Restriction { return $this->type; } - else - { - return null; - } + + return null; } /** @@ -146,9 +142,7 @@ class SimplePie_Restriction { return $this->value; } - else - { - return null; - } + + return null; } } diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index c55ee50b7..8b7e57926 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -429,7 +429,7 @@ class SimplePie_Sanitize } else { - trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); + trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); } } } diff --git a/lib/SimplePie/SimplePie/Source.php b/lib/SimplePie/SimplePie/Source.php index 1a66a392d..8fac13ef7 100644 --- a/lib/SimplePie/SimplePie/Source.php +++ b/lib/SimplePie/SimplePie/Source.php @@ -79,10 +79,8 @@ class SimplePie_Source { return $this->data['child'][$namespace][$tag]; } - else - { - return null; - } + + return null; } public function get_base($element = array()) @@ -130,10 +128,8 @@ class SimplePie_Source { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } - else - { - return null; - } + + return null; } public function get_category($key = 0) @@ -143,10 +139,8 @@ class SimplePie_Source { return $categories[$key]; } - else - { - return null; - } + + return null; } public function get_categories() @@ -200,10 +194,8 @@ class SimplePie_Source { return array_unique($categories); } - else - { - return null; - } + + return null; } public function get_author($key = 0) @@ -213,10 +205,8 @@ class SimplePie_Source { return $authors[$key]; } - else - { - return null; - } + + return null; } public function get_authors() @@ -283,10 +273,8 @@ class SimplePie_Source { return array_unique($authors); } - else - { - return null; - } + + return null; } public function get_contributor($key = 0) @@ -296,10 +284,8 @@ class SimplePie_Source { return $contributors[$key]; } - else - { - return null; - } + + return null; } public function get_contributors() @@ -354,10 +340,8 @@ class SimplePie_Source { return array_unique($contributors); } - else - { - return null; - } + + return null; } public function get_link($key = 0, $rel = 'alternate') @@ -367,10 +351,8 @@ class SimplePie_Source { return $links[$key]; } - else - { - return null; - } + + return null; } /** @@ -449,10 +431,8 @@ class SimplePie_Source { return $this->data['links'][$rel]; } - else - { - return null; - } + + return null; } public function get_description() @@ -493,10 +473,8 @@ class SimplePie_Source { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); } - else - { - return null; - } + + return null; } public function get_copyright() @@ -521,10 +499,8 @@ class SimplePie_Source { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); } - else - { - return null; - } + + return null; } public function get_language() @@ -545,10 +521,8 @@ class SimplePie_Source { return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); } - else - { - return null; - } + + return null; } public function get_latitude() @@ -561,10 +535,8 @@ class SimplePie_Source { return (float) $match[1]; } - else - { - return null; - } + + return null; } public function get_longitude() @@ -581,10 +553,8 @@ class SimplePie_Source { return (float) $match[2]; } - else - { - return null; - } + + return null; } public function get_image_url() @@ -601,10 +571,7 @@ class SimplePie_Source { return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); } - else - { - return null; - } + + return null; } } - diff --git a/lib/SimplePie/SimplePie/XML/Declaration/Parser.php b/lib/SimplePie/SimplePie/XML/Declaration/Parser.php index 99e751672..18ca1b79b 100644 --- a/lib/SimplePie/SimplePie/XML/Declaration/Parser.php +++ b/lib/SimplePie/SimplePie/XML/Declaration/Parser.php @@ -136,13 +136,11 @@ class SimplePie_XML_Declaration_Parser { return true; } - else - { - $this->version = ''; - $this->encoding = ''; - $this->standalone = ''; - return false; - } + + $this->version = ''; + $this->encoding = ''; + $this->standalone = ''; + return false; } /** diff --git a/lib/SimplePie/SimplePie/gzdecode.php b/lib/SimplePie/SimplePie/gzdecode.php index 0e8bc8fc6..f4aeafa28 100644 --- a/lib/SimplePie/SimplePie/gzdecode.php +++ b/lib/SimplePie/SimplePie/gzdecode.php @@ -338,10 +338,8 @@ class SimplePie_gzdecode { return false; } - else - { - $this->position = $this->compressed_size - 8; - } + + $this->position = $this->compressed_size - 8; // Check CRC of data $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4))); @@ -362,9 +360,7 @@ class SimplePie_gzdecode // Wow, against all odds, we've actually got a valid gzip string return true; } - else - { - return false; - } + + return false; } } diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 4087f6faf..333920c8c 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -102,6 +102,23 @@ function safe_ascii($text) { return filter_var($text, FILTER_DEFAULT, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH); } +function escapeToUnicodeAlternative($text, $extended = true) { + $text = htmlspecialchars_decode($text, ENT_QUOTES); + + //Problematic characters + $problem = array('&', '<', '>'); + //Use their fullwidth Unicode form instead: + $replace = array('&', '<', '>'); + + // https://raw.githubusercontent.com/mihaip/google-reader-api/master/wiki/StreamId.wiki + if ($extended) { + $problem += array("'", '"', '^', '?', '\\', '/', ',', ';'); + $replace += array("’", '"', '^', '?', '\', '/', ',', ';'); + } + + return trim(str_replace($problem, $replace, $text)); +} + /** * Test if a given server address is publicly accessible. * @@ -209,6 +226,7 @@ function customSimplePie($attributes = array()) { 'font', 'form', 'frame', 'frameset', 'html', 'link', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'plaintext', 'script', 'style', + 'svg', //TODO: Support SVG after sanitizing and URL rewriting of xlink:href )); $simplePie->strip_attributes(array_merge($simplePie->strip_attributes, array( 'autoplay', 'class', 'onload', 'onunload', 'onclick', 'ondblclick', 'onmousedown', 'onmouseup', diff --git a/p/api/greader.php b/p/api/greader.php index c6701096c..7cd312f2c 100644 --- a/p/api/greader.php +++ b/p/api/greader.php @@ -19,6 +19,7 @@ Server-side API compatible with Google Reader API layer 2 * https://github.com/devongovett/reader * https://github.com/theoldreader/api * https://www.inoreader.com/developers/ +* https://feedhq.readthedocs.io/en/latest/api/index.html */ require(__DIR__ . '/../../constants.php'); @@ -198,6 +199,7 @@ function clientLogin($email, $pass) { //http://web.archive.org/web/2013060409104 header('Content-Type: text/plain; charset=UTF-8'); $auth = $email . '/' . sha1(FreshRSS_Context::$system_conf->salt . $email . FreshRSS_Context::$user_conf->apiPasswordHash); echo 'SID=', $auth, "\n", + 'LSID=null', "\n", //Vienna RSS 'Auth=', $auth, "\n"; exit(); } else { @@ -258,7 +260,7 @@ function tagList() { foreach ($res as $cName) { $tags[] = array( - 'id' => 'user/-/label/' . $cName, + 'id' => 'user/-/label/' . htmlspecialchars_decode($cName, ENT_QUOTES), //'sortid' => $cName, 'type' => 'folder', //Inoreader ); @@ -270,7 +272,7 @@ function tagList() { $labels = $tagDAO->listTags(true); foreach ($labels as $label) { $tags[] = array( - 'id' => 'user/-/label/' . $label->name(), + 'id' => 'user/-/label/' . htmlspecialchars_decode($label->name(), ENT_QUOTES), //'sortid' => $cName, 'type' => 'tag', //Inoreader 'unread_count' => $label->nbUnread(), //Inoreader @@ -298,17 +300,17 @@ function subscriptionList() { foreach ($res as $line) { $subscriptions[] = array( 'id' => 'feed/' . $line['id'], - 'title' => $line['name'], + 'title' => escapeToUnicodeAlternative($line['name'], true), 'categories' => array( array( - 'id' => 'user/-/label/' . $line['c_name'], - 'label' => $line['c_name'], + 'id' => 'user/-/label/' . htmlspecialchars_decode($line['c_name'], ENT_QUOTES), + 'label' => htmlspecialchars_decode($line['c_name'], ENT_QUOTES), ), ), //'sortid' => $line['name'], //'firstitemmsec' => 0, - 'url' => $line['url'], - 'htmlUrl' => $line['website'], + 'url' => htmlspecialchars_decode($line['url'], ENT_QUOTES), + 'htmlUrl' => htmlspecialchars_decode($line['website'], ENT_QUOTES), 'iconUrl' => $faviconsUrl . hash('crc32b', $salt . $line['url']), ); } @@ -345,6 +347,7 @@ function subscriptionEdit($streamNames, $titles, $action, $add = '', $remove = ' $c_name = ''; } } + $c_name = htmlspecialchars($c_name, ENT_COMPAT, 'UTF-8'); $cat = $categoryDAO->searchByName($c_name); $addCatId = $cat == null ? 0 : $cat->id(); } else if ($remove != '' && strpos($remove, 'user/-/label/')) { @@ -355,26 +358,28 @@ function subscriptionEdit($streamNames, $titles, $action, $add = '', $remove = ' badRequest(); } for ($i = count($streamNames) - 1; $i >= 0; $i--) { - $streamName = $streamNames[$i]; //feed/http://example.net/sample.xml ; feed/338 - if (strpos($streamName, 'feed/') === 0) { - $streamName = substr($streamName, 5); + $streamUrl = $streamNames[$i]; //feed/http://example.net/sample.xml ; feed/338 + if (strpos($streamUrl, 'feed/') === 0) { + $streamUrl = substr($streamUrl, 5); $feedId = 0; - if (ctype_digit($streamName)) { + if (ctype_digit($streamUrl)) { if ($action === 'subscribe') { continue; } - $feedId = $streamName; + $feedId = $streamUrl; } else { - $feed = $feedDAO->searchByUrl($streamName); + $streamUrl = htmlspecialchars($streamUrl, ENT_COMPAT, 'UTF-8'); + $feed = $feedDAO->searchByUrl($streamUrl); $feedId = $feed == null ? -1 : $feed->id(); } $title = isset($titles[$i]) ? $titles[$i] : ''; + $title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8'); switch ($action) { case 'subscribe': if ($feedId <= 0) { - $http_auth = ''; //TODO + $http_auth = ''; try { - $feed = FreshRSS_feed_Controller::addFeed($streamName, $title, $addCatId, $c_name, $http_auth); + $feed = FreshRSS_feed_Controller::addFeed($streamUrl, $title, $addCatId, $c_name, $http_auth); continue; } catch (Exception $e) { Minz_Log::error('subscriptionEdit error subscribe: ' . $e->getMessage(), API_LOG); @@ -407,6 +412,7 @@ function subscriptionEdit($streamNames, $titles, $action, $add = '', $remove = ' function quickadd($url) { try { + $url = htmlspecialchars($url, ENT_COMPAT, 'UTF-8'); $feed = FreshRSS_feed_Controller::addFeed($url); exit(json_encode(array( 'numResults' => 1, @@ -442,7 +448,7 @@ function unreadCount() { //http://blog.martindoms.com/2009/10/16/using-the-googl } } $unreadcounts[] = array( - 'id' => 'user/-/label/' . $cat->name(), + 'id' => 'user/-/label/' . htmlspecialchars_decode($cat->name(), ENT_QUOTES), 'count' => $cat->nbNotRead(), 'newestItemTimestampUsec' => $catLastUpdate . '000000', ); @@ -455,7 +461,7 @@ function unreadCount() { //http://blog.martindoms.com/2009/10/16/using-the-googl $tagDAO = FreshRSS_Factory::createTagDao(); foreach ($tagDAO->listTags(true) as $label) { $unreadcounts[] = array( - 'id' => 'user/-/label/' . $label->name(), + 'id' => 'user/-/label/' . htmlspecialchars_decode($label->name(), ENT_QUOTES), 'count' => $label->nbUnread(), ); } @@ -496,28 +502,29 @@ function entriesToArray($entries) { $f_name = '_'; } $item = array( - 'id' => /*'tag:google.com,2005:reader/item/' .*/ dec2hex($entry->id()), //64-bit hexa http://code.google.com/p/google-reader-api/wiki/ItemId + 'id' => 'tag:google.com,2005:reader/item/' . dec2hex($entry->id()), //64-bit hexa http://code.google.com/p/google-reader-api/wiki/ItemId 'crawlTimeMsec' => substr($entry->id(), 0, -3), 'timestampUsec' => '' . $entry->id(), //EasyRSS 'published' => $entry->date(true), - 'title' => $entry->title(), + 'title' => escapeToUnicodeAlternative($entry->title(), false), 'summary' => array('content' => $entry->content()), 'alternate' => array( array('href' => htmlspecialchars_decode($entry->link(), ENT_QUOTES)), ), 'categories' => array( 'user/-/state/com.google/reading-list', - 'user/-/label/' . $c_name, + 'user/-/label/' . htmlspecialchars_decode($c_name, ENT_QUOTES), ), 'origin' => array( 'streamId' => 'feed/' . $f_id, - 'title' => $f_name, //EasyRSS + 'title' => escapeToUnicodeAlternative($f_name, true), //EasyRSS //'htmlUrl' => $line['f_website'], ), ); $author = $entry->authors(true); + $author = trim($author, '; '); if ($author != '') { - $item['author'] = $author; + $item['author'] = escapeToUnicodeAlternative($author, false); } if ($entry->isRead()) { $item['categories'][] = 'user/-/state/com.google/read'; @@ -527,69 +534,117 @@ function entriesToArray($entries) { } $tagNames = isset($entryIdsTagNames['e_' . $entry->id()]) ? $entryIdsTagNames['e_' . $entry->id()] : array(); foreach ($tagNames as $tagName) { - $item['categories'][] = 'user/-/label/' . $tagName; + $item['categories'][] = 'user/-/label/' . htmlspecialchars_decode($tagName, ENT_QUOTES); } $items[] = $item; } return $items; } -function streamContents($path, $include_target, $start_time, $count, $order, $exclude_target, $continuation) { -//http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI -//http://blog.martindoms.com/2009/10/16/using-the-google-reader-api-part-2/#feed - header('Content-Type: application/json; charset=UTF-8'); - - switch ($path) { - case 'reading-list': - $type = 'A'; - break; - case 'starred': - $type = 's'; - break; - case 'feed': - $type = 'f'; +function streamContentsFilters($type, $streamId, $filter_target, $exclude_target, $start_time, $stop_time) { + switch ($type) { + case 'f': //feed + if ($streamId != '' && !ctype_digit($streamId)) { + $feedDAO = FreshRSS_Factory::createFeedDao(); + $streamId = htmlspecialchars($streamId, ENT_COMPAT, 'UTF-8'); + $feed = $feedDAO->searchByUrl($streamId); + $streamId = $feed == null ? -1 : $feed->id(); + } break; - case 'label': + case 'c': //category or label $categoryDAO = FreshRSS_Factory::createCategoryDao(); - $cat = $categoryDAO->searchByName($include_target); + $streamId = htmlspecialchars($streamId, ENT_COMPAT, 'UTF-8'); + $cat = $categoryDAO->searchByName($streamId); if ($cat != null) { $type = 'c'; - $include_target = $cat->id(); + $streamId = $cat->id(); } else { $tagDAO = FreshRSS_Factory::createTagDao(); - $tag = $tagDAO->searchByName($include_target); + $tag = $tagDAO->searchByName($streamId); if ($tag != null) { $type = 't'; - $include_target = $tag->id(); + $streamId = $tag->id(); } else { $type = 'A'; - $include_target = -1; + $streamId = -1; } } break; + } + + switch ($filter_target) { + case 'user/-/state/com.google/read': + $state = FreshRSS_Entry::STATE_READ; + break; + case 'user/-/state/com.google/unread': + $state = FreshRSS_Entry::STATE_NOT_READ; + break; + case 'user/-/state/com.google/starred': + $state = FreshRSS_Entry::STATE_FAVORITE; + break; default: - $type = 'A'; + $state = FreshRSS_Entry::STATE_ALL; break; } switch ($exclude_target) { case 'user/-/state/com.google/read': - $state = FreshRSS_Entry::STATE_NOT_READ; + $state &= FreshRSS_Entry::STATE_NOT_READ; break; case 'user/-/state/com.google/unread': - $state = FreshRSS_Entry::STATE_READ; + $state &= FreshRSS_Entry::STATE_READ; + break; + case 'user/-/state/com.google/starred': + $state &= FreshRSS_Entry::STATE_NOT_FAVORITE; + break; + } + + $searches = new FreshRSS_BooleanSearch(''); + if ($start_time != '') { + $search = new FreshRSS_Search(''); + $search->setMinDate($start_time); + $searches->add($search); + } + if ($stop_time != '') { + $search = new FreshRSS_Search(''); + $search->setMaxDate($stop_time); + $searches->add($search); + } + + return array($type, $streamId, $state, $searches); +} + +function streamContents($path, $include_target, $start_time, $stop_time, $count, $order, $filter_target, $exclude_target, $continuation) { +//http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI +//http://blog.martindoms.com/2009/10/16/using-the-google-reader-api-part-2/#feed + header('Content-Type: application/json; charset=UTF-8'); + + switch ($path) { + case 'reading-list': + $type = 'A'; + break; + case 'starred': + $type = 's'; + break; + case 'feed': + $type = 'f'; + break; + case 'label': + $type = 'c'; break; default: - $state = FreshRSS_Entry::STATE_ALL; + $type = 'A'; break; } + list($type, $include_target, $state, $searches) = streamContentsFilters($type, $include_target, $filter_target, $exclude_target, $start_time, $stop_time); + if ($continuation != '') { $count++; //Shift by one element } $entryDAO = FreshRSS_Factory::createEntryDao(); - $entries = $entryDAO->listWhere($type, $include_target, $state, $order === 'o' ? 'ASC' : 'DESC', $count, $continuation, new FreshRSS_BooleanSearch(''), $start_time); + $entries = $entryDAO->listWhere($type, $include_target, $state, $order === 'o' ? 'ASC' : 'DESC', $count, $continuation, $searches); $items = entriesToArray($entries); @@ -614,7 +669,7 @@ function streamContents($path, $include_target, $start_time, $count, $order, $ex exit(); } -function streamContentsItemsIds($streamId, $start_time, $count, $order, $exclude_target, $continuation) { +function streamContentsItemsIds($streamId, $start_time, $stop_time, $count, $order, $filter_target, $exclude_target, $continuation) { //http://code.google.com/p/google-reader-api/wiki/ApiStreamItemsIds //http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI //http://blog.martindoms.com/2009/10/16/using-the-google-reader-api-part-2/#feed @@ -622,55 +677,32 @@ function streamContentsItemsIds($streamId, $start_time, $count, $order, $exclude $id = ''; if ($streamId === 'user/-/state/com.google/reading-list') { $type = 'A'; - } elseif ('user/-/state/com.google/starred') { + } elseif ($streamId === 'user/-/state/com.google/starred') { $type = 's'; } elseif (strpos($streamId, 'feed/') === 0) { $type = 'f'; - $id = basename($streamId); + $streamId = substr($streamId, 5); } elseif (strpos($streamId, 'user/-/label/') === 0) { $type = 'c'; - $c_name = substr($streamId, 13); - $categoryDAO = FreshRSS_Factory::createCategoryDao(); - $cat = $categoryDAO->searchByName($c_name); - if ($cat != null) { - $type = 'c'; - $id = $cat->id(); - } else { - $tagDAO = FreshRSS_Factory::createTagDao(); - $tag = $tagDAO->searchByName($c_name); - if ($tag != null) { - $type = 't'; - $id = $tag->id(); - } else { - $type = 'A'; - $id = -1; - } - } + $streamId = substr($streamId, 13); } - switch ($exclude_target) { - case 'user/-/state/com.google/read': - $state = FreshRSS_Entry::STATE_NOT_READ; - break; - default: - $state = FreshRSS_Entry::STATE_ALL; - break; - } + list($type, $id, $state, $searches) = streamContentsFilters($type, $streamId, $filter_target, $exclude_target, $start_time, $stop_time); if ($continuation != '') { $count++; //Shift by one element } $entryDAO = FreshRSS_Factory::createEntryDao(); - $ids = $entryDAO->listIdsWhere($type, $id, $state, $order === 'o' ? 'ASC' : 'DESC', $count, $continuation, new FreshRSS_BooleanSearch(''), $start_time); + $ids = $entryDAO->listIdsWhere($type, $id, $state, $order === 'o' ? 'ASC' : 'DESC', $count, $continuation, $searches); if ($continuation != '') { array_shift($ids); //Discard first element that was already sent in the previous response $count--; } - if (empty($ids)) { //For News+ bug https://github.com/noinnion/newsplus/issues/84#issuecomment-57834632 - $ids[] = 0; + if (empty($ids) && isset($_GET['client']) && $_GET['client'] === 'newsplus') { + $ids[] = 0; //For News+ bug https://github.com/noinnion/newsplus/issues/84#issuecomment-57834632 } $itemRefs = array(); foreach ($ids as $id) { @@ -697,7 +729,10 @@ function streamContentsItems($e_ids, $order) { header('Content-Type: application/json; charset=UTF-8'); foreach ($e_ids as $i => $e_id) { - $e_ids[$i] = hex2dec(basename($e_id)); //Strip prefix 'tag:google.com,2005:reader/item/' + if (strpos($e_id, '/') !== null) { + $e_id = hex2dec(basename($e_id)); //Strip prefix 'tag:google.com,2005:reader/item/' + } + $e_ids[$i] = $e_id; } $entryDAO = FreshRSS_Factory::createEntryDao(); @@ -717,7 +752,10 @@ function streamContentsItems($e_ids, $order) { function editTag($e_ids, $a, $r) { foreach ($e_ids as $i => $e_id) { - $e_ids[$i] = hex2dec(basename($e_id)); //Strip prefix 'tag:google.com,2005:reader/item/' + if (strpos($e_id, '/') !== null) { + $e_id = hex2dec(basename($e_id)); //Strip prefix 'tag:google.com,2005:reader/item/' + } + $e_ids[$i] = $e_id; } $entryDAO = FreshRSS_Factory::createEntryDao(); @@ -748,6 +786,7 @@ function editTag($e_ids, $a, $r) { } } if ($tagName != '') { + $tagName = htmlspecialchars($tagName, ENT_COMPAT, 'UTF-8'); $tag = $tagDAO->searchByName($tagName); if ($tag == null) { $tagDAO->addTag(array('name' => $tagName)); @@ -771,6 +810,7 @@ function editTag($e_ids, $a, $r) { default: if (strpos($r, 'user/-/label/') === 0) { $tagName = substr($r, 13); + $tagName = htmlspecialchars($tagName, ENT_COMPAT, 'UTF-8'); $tag = $tagDAO->searchByName($tagName); if ($tag != null) { foreach ($e_ids as $e_id) { @@ -788,7 +828,9 @@ function renameTag($s, $dest) { if ($s != '' && strpos($s, 'user/-/label/') === 0 && $dest != '' && strpos($dest, 'user/-/label/') === 0) { $s = substr($s, 13); + $s = htmlspecialchars($s, ENT_COMPAT, 'UTF-8'); $dest = substr($dest, 13); + $dest = htmlspecialchars($dest, ENT_COMPAT, 'UTF-8'); $categoryDAO = FreshRSS_Factory::createCategoryDao(); $cat = $categoryDAO->searchByName($s); @@ -810,6 +852,7 @@ function renameTag($s, $dest) { function disableTag($s) { if ($s != '' && strpos($s, 'user/-/label/') === 0) { $s = substr($s, 13); + $s = htmlspecialchars($s, ENT_COMPAT, 'UTF-8'); $categoryDAO = FreshRSS_Factory::createCategoryDao(); $cat = $categoryDAO->searchByName($s); if ($cat != null) { @@ -838,6 +881,7 @@ function markAllAsRead($streamId, $olderThanId) { $entryDAO->markReadFeed($f_id, $olderThanId); } elseif (strpos($streamId, 'user/-/label/') === 0) { $c_name = substr($streamId, 13); + $c_name = htmlspecialchars($c_name, ENT_COMPAT, 'UTF-8'); $categoryDAO = FreshRSS_Factory::createCategoryDao(); $cat = $categoryDAO->searchByName($c_name); if ($cat != null) { @@ -902,12 +946,14 @@ if (count($pathInfos) < 3) { * exclude items from a particular feed (obviously not useful in this * request, but xt appears in other listing requests). */ $exclude_target = isset($_GET['xt']) ? $_GET['xt'] : ''; + $filter_target = isset($_GET['it']) ? $_GET['it'] : ''; $count = isset($_GET['n']) ? intval($_GET['n']) : 20; //n=[integer] : The maximum number of results to return. $order = isset($_GET['r']) ? $_GET['r'] : 'd'; //r=[d|n|o] : Sort order of item results. d or n gives items in descending date order, o in ascending order. /* ot=[unix timestamp] : The time from which you want to retrieve * items. Only items that have been crawled by Google Reader after * this time will be returned. */ $start_time = isset($_GET['ot']) ? intval($_GET['ot']) : 0; + $stop_time = isset($_GET['nt']) ? intval($_GET['nt']) : 0; /* Continuation token. If a StreamContents response does not represent * all items in a timestamp range, it will have a continuation attribute. * The same request can be re-issued with the value of that attribute put @@ -920,23 +966,31 @@ if (count($pathInfos) < 3) { if (isset($pathInfos[7])) { if ($pathInfos[6] === 'feed') { $include_target = $pathInfos[7]; - StreamContents($pathInfos[6], $include_target, $start_time, $count, $order, $exclude_target, $continuation); + if ($include_target != '' && !ctype_digit($include_target)) { + $include_target = empty($_SERVER['REQUEST_URI']) ? '' : $_SERVER['REQUEST_URI']; + if (preg_match('#/reader/api/0/stream/contents/feed/([A-Za-z0-9\'!*()%$_.~+-]+)#', $include_target, $matches) && isset($matches[1])) { + $include_target = urldecode($matches[1]); + } else { + $include_target = ''; + } + } + streamContents($pathInfos[6], $include_target, $start_time, $stop_time, $count, $order, $filter_target, $exclude_target, $continuation); } elseif ($pathInfos[6] === 'user' && isset($pathInfos[8]) && isset($pathInfos[9])) { if ($pathInfos[8] === 'state') { if ($pathInfos[9] === 'com.google' && isset($pathInfos[10])) { if ($pathInfos[10] === 'reading-list' || $pathInfos[10] === 'starred') { $include_target = ''; - streamContents($pathInfos[10], $include_target, $start_time, $count, $order, $exclude_target, $continuation); + streamContents($pathInfos[10], $include_target, $start_time, $stop_time, $count, $order, $filter_target, $exclude_target, $continuation); } } } elseif ($pathInfos[8] === 'label') { $include_target = $pathInfos[9]; - streamContents($pathInfos[8], $include_target, $start_time, $count, $order, $exclude_target, $continuation); + streamContents($pathInfos[8], $include_target, $start_time, $stop_time, $count, $order, $filter_target, $exclude_target, $continuation); } } } else { //EasyRSS $include_target = ''; - streamContents('reading-list', $include_target, $start_time, $count, $order, $exclude_target, $continuation); + streamContents('reading-list', $include_target, $start_time, $stop_time, $count, $order, $filter_target, $exclude_target, $continuation); } } elseif ($pathInfos[5] === 'items') { if ($pathInfos[6] === 'ids' && isset($_GET['s'])) { @@ -944,7 +998,7 @@ if (count($pathInfos) < 3) { * be repeated to fetch the item IDs from multiple streams at once * (more efficient from a backend perspective than multiple requests). */ $streamId = $_GET['s']; - streamContentsItemsIds($streamId, $start_time, $count, $order, $exclude_target, $continuation); + streamContentsItemsIds($streamId, $start_time, $stop_time, $count, $order, $filter_target, $exclude_target, $continuation); } else if ($pathInfos[6] === 'contents' && isset($_POST['i'])) { //FeedMe $e_ids = multiplePosts('i'); //item IDs streamContentsItems($e_ids, $order); diff --git a/p/api/index.php b/p/api/index.php index 108841819..ee37b794b 100644 --- a/p/api/index.php +++ b/p/api/index.php @@ -2,13 +2,13 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB"> <head> <meta charset="UTF-8" /> -<title>FreshRSS API</title> +<title>FreshRSS API endpoints</title> <meta name="robots" content="noindex" /> <link rel="start" href="../i/" /> </head> <body> -<h1>FreshRSS API</h1> +<h1>FreshRSS API endpoints</h1> <h2>Google Reader compatible API</h2> <dl> diff --git a/p/api/pshb.php b/p/api/pshb.php index ac78bfd74..b6f03593d 100644 --- a/p/api/pshb.php +++ b/p/api/pshb.php @@ -79,7 +79,7 @@ if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] === 'subscribe') { } $hubJson['lease_start'] = time(); if (!isset($hubJson['error'])) { - $hubJson['error'] = true; //Do not assume that PubSubHubbub works until the first successul push + $hubJson['error'] = true; //Do not assume that WebSub works until the first successul push } file_put_contents('./!hub.json', json_encode($hubJson)); header('Connection: close'); @@ -162,5 +162,5 @@ if ($nb === 0) { file_put_contents('./!hub.json', json_encode($hubJson)); } -Minz_Log::notice('PubSubHubbub ' . $self . ' done: ' . $nb, PSHB_LOG); +Minz_Log::notice('WebSub ' . $self . ' done: ' . $nb, PSHB_LOG); exit('Done: ' . $nb . "\n"); diff --git a/p/scripts/jquery.sticky-kit.min.js b/p/scripts/jquery.sticky-kit.min.js deleted file mode 100644 index e2a3c6de9..000000000 --- a/p/scripts/jquery.sticky-kit.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net -*/ -(function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k)); -if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("<div />"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q, -u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),e<F&&(m=!1,c=q,null==p&&("left"!==r&&"right"!==r||a.insertAfter(h), -h.detach()),b={position:"",width:"",top:""},a.css(b).removeClass(t).trigger("sticky_kit:unstick")),B&&(b=f.height(),u+q>b&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}), -a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize", -y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n<K;n++)d=this[n],J(b(d));return this}}).call(this); diff --git a/p/scripts/main.js b/p/scripts/main.js index f96828048..4ba329dc1 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -237,29 +237,29 @@ function mark_favorite(active) { }); } -function toggleContent(new_active, old_active) { +function toggleContent(new_active, old_active, skipping) { + // If skipping, move current without activating or marking as read if (new_active.length === 0) { return; } - if (context.does_lazyload) { + if (context.does_lazyload && !skipping) { new_active.find('img[data-original], iframe[data-original]').each(function () { - this.onload = function () { $(document.body).trigger("sticky_kit:recalc"); }; this.setAttribute('src', this.getAttribute('data-original')); this.removeAttribute('data-original'); }); } if (old_active[0] !== new_active[0]) { - if (isCollapsed) { + if (isCollapsed && !skipping) { // BUG?: isCollapsed can only ever be true new_active.addClass("active"); } old_active.removeClass("active current"); new_active.addClass("current"); - if (context.auto_remove_article && !old_active.hasClass('not_read')) { + if (context.auto_remove_article && !old_active.hasClass('not_read') && !skipping) { auto_remove(old_active); } - } else { + } else { // collapse_entry calls toggleContent(flux_current, flux_current, false) new_active.toggleClass('active'); } @@ -278,6 +278,10 @@ function toggleContent(new_active, old_active) { } } + if (skipping) { + // when skipping, this feels more natural if it's not so near the top + new_pos -= $(window).height() / 4; + } if (context.hide_posts) { if (relative_move) { new_pos += old_scroll; @@ -295,7 +299,7 @@ function toggleContent(new_active, old_active) { } } - if (context.auto_mark_article && new_active.hasClass('active')) { + if (context.auto_mark_article && new_active.hasClass('active') && !skipping) { mark_read(new_active, true); } } @@ -313,13 +317,29 @@ function auto_remove(element) { function prev_entry() { var old_active = $(".flux.current"), new_active = old_active.length === 0 ? $(".flux:last") : old_active.prevAll(".flux:first"); - toggleContent(new_active, old_active); + toggleContent(new_active, old_active, false); } function next_entry() { var old_active = $(".flux.current"), new_active = old_active.length === 0 ? $(".flux:first") : old_active.nextAll(".flux:first"); - toggleContent(new_active, old_active); + toggleContent(new_active, old_active, false); + + if (new_active.nextAll().length < 3) { + load_more_posts(); + } +} + +function skip_prev_entry() { + var old_active = $(".flux.current"), + new_active = old_active.length === 0 ? $(".flux:last") : old_active.prevAll(".flux:first"); + toggleContent(new_active, old_active, true); +} + +function skip_next_entry() { + var old_active = $(".flux.current"), + new_active = old_active.length === 0 ? $(".flux:first") : old_active.nextAll(".flux:first"); + toggleContent(new_active, old_active, true); if (new_active.nextAll().length < 3) { load_more_posts(); @@ -402,7 +422,7 @@ function last_category() { function collapse_entry() { var flux_current = $(".flux.current"); - toggleContent(flux_current, flux_current); + toggleContent(flux_current, flux_current, false); } function user_filter(key) { @@ -507,29 +527,8 @@ function init_posts() { } } -function inject_script(name) { - var script = document.createElement('script'); - script.async = 'async'; - script.defer = 'defer'; - script.src = '../scripts/' + name; - document.head.appendChild(script); -} - -function init_sticky_column() { - if (!window.$ || !window.$.fn.stick_in_parent) { - if (window.console) { - console.log('FreshRSS waiting for Sticky-kit…'); - } - window.setTimeout(init_sticky_column, 200); - return; - } - if ($('.toggle_aside').css('display') === 'none') { - $('#aside_feed .tree').stick_in_parent({parent:'#aside_feed'}); - } -} - function init_column_categories() { - if (context.current_view !== 'normal') { + if (context.current_view !== 'normal' && context.current_view !== 'reader') { return; } @@ -543,38 +542,43 @@ function init_column_categories() { this.alt = '▽'; } }); - $(this).parent().next(".tree-folder-items").slideToggle(300 , function() { $(document.body).trigger("sticky_kit:recalc"); }); + $(this).parent().next(".tree-folder-items").slideToggle(300, function () { + //Workaround for Gecko bug in Firefox 64-65(+?): + var sidebar = document.getElementById('sidebar'); + if (sidebar && sidebar.scrollHeight > sidebar.clientHeight && //if needs scrollbar + sidebar.scrollWidth >= sidebar.offsetWidth) { //but no scrollbar + sidebar.style['overflow-y'] = 'scroll'; //then force scrollbar + setTimeout(function () { sidebar.style['overflow-y'] = ''; }, 0); + } + }); return false; }); + $('#aside_feed').on('click', '.tree-folder-items .feed .dropdown-toggle', function () { - if ($(this).nextAll('.dropdown-menu').length === 0) { - var itemId = $(this).closest('.item').attr('id'), - templateId = itemId.substring(0, 2) === 't_' ? 'tag_config_template' : 'feed_config_template', - id = itemId.substr(2), - feed_web = $(this).data('fweb'), - template = $('#' + templateId) - .html().replace(/------/g, id).replace('http://example.net/', feed_web); + var itemId = $(this).closest('.item').attr('id'), + templateId = itemId.substring(0, 2) === 't_' ? 'tag_config_template' : 'feed_config_template', + id = itemId.substr(2), + feed_web = $(this).data('fweb'), + template = $('#' + templateId) + .html().replace(/------/g, id).replace('http://example.net/', feed_web); + if ($(this).next('.dropdown-menu').length === 0) { $(this).attr('href', '#dropdown-' + id).prev('.dropdown-target').attr('id', 'dropdown-' + id).parent() .append(template).find('button.confirm').removeAttr('disabled'); - $('.tree-folder-items .dropdown-close a').click(function(){ - $('.tree').removeClass('treepadding'); - $(document.body).trigger("sticky_kit:recalc"); - }); + } else { + if ($(this).next('.dropdown-menu').css('display') === 'none') { + id = $(this).closest('.item').attr('id').substr(2); + $(this).attr('href', '#dropdown-' + id); + } else { + $(this).attr('href', "#close"); + } } }); - - $('.tree-folder-items .dropdown-toggle').click(function(){ - $('.tree').addClass('treepadding'); - $(document.body).trigger("sticky_kit:recalc"); - }); - - init_sticky_column(); } function init_shortcuts() { if (!(window.shortcut && window.shortcuts)) { if (window.console) { - console.log('FreshRSS waiting for sortcut.js…'); + console.log('FreshRSS waiting for shortcut.js…'); } window.setTimeout(init_shortcuts, 200); return; @@ -637,12 +641,15 @@ function init_shortcuts() { shortcut.add(shortcuts.prev_entry, prev_entry, { 'disable_in_input': true }); + shortcut.add(shortcuts.skip_prev_entry, skip_prev_entry, { + 'disable_in_input': true + }); shortcut.add(shortcuts.first_entry, function () { var old_active = $(".flux.current"), first = $(".flux:first"); if (first.hasClass("flux")) { - toggleContent(first, old_active); + toggleContent(first, old_active, false); } }, { 'disable_in_input': true @@ -650,12 +657,15 @@ function init_shortcuts() { shortcut.add(shortcuts.next_entry, next_entry, { 'disable_in_input': true }); + shortcut.add(shortcuts.skip_next_entry, skip_next_entry, { + 'disable_in_input': true + }); shortcut.add(shortcuts.last_entry, function () { var old_active = $(".flux.current"), last = $(".flux:last"); if (last.hasClass("flux")) { - toggleContent(last, old_active); + toggleContent(last, old_active, false); } }, { 'disable_in_input': true @@ -752,7 +762,7 @@ function init_shortcuts() { function init_stream(divStream) { divStream.on('click', '.flux_header,.flux_content', function (e) { //flux_toggle - if ($(e.target).closest('.keep_unread, .content, .item.website, .item.link, .dropdown-menu').length > 0) { + if ($(e.target).closest('.content, .item.website, .item.link, .dropdown-menu').length > 0) { return; } if (!context.sides_close_article && $(e.target).is('div.flux_content')) { @@ -768,7 +778,7 @@ function init_stream(divStream) { } return true; } - toggleContent(new_active, old_active); + toggleContent(new_active, old_active, false); }); divStream.on('click', '.flux a.read', function () { @@ -827,8 +837,10 @@ function init_stream(divStream) { } } +var $nav_entries = null; + function init_nav_entries() { - var $nav_entries = $('#nav_entries'); + $nav_entries = $('#nav_entries'); $nav_entries.find('.previous_entry').click(function () { prev_entry(); return false; @@ -1166,7 +1178,6 @@ function load_more_posts() { $('#load_more').removeClass('loading'); $('#bigMarkAsRead').removeAttr('disabled'); load_more = false; - $(document.body).trigger('sticky_kit:recalc'); }); } @@ -1259,8 +1270,6 @@ function init_crypto_form() { } //</crypto form (Web login)> - - function init_confirm_action() { $('body').on('click', '.confirm', function () { var str_confirmation = $(this).attr('data-str-confirm'); @@ -1274,13 +1283,13 @@ function init_confirm_action() { } function init_print_action() { - $('.item.share > a[href="#"]').click(function () { + $('.item.share > a[href="#"]').click(function (e) { var content = "<html><head><style>" + "body { font-family: Serif; text-align: justify; }" + "a { color: #000; text-decoration: none; }" + "a:after { content: ' [' attr(href) ']'}" + "</style></head><body>" + - $(".flux.current .content").html() + + $(e.target).closest('.flux_content').find('.content').html() + "</body></html>"; var tmp_window = window.open(); @@ -1509,7 +1518,6 @@ function init_beforeDOM() { return; } if (['normal', 'reader', 'global'].indexOf(context.current_view) >= 0) { - inject_script('jquery.sticky-kit.min.js'); init_normal(); } } diff --git a/p/themes/BlueLagoon/BlueLagoon.css b/p/themes/BlueLagoon/BlueLagoon.css index 164088f4b..94eb8e3a8 100644 --- a/p/themes/BlueLagoon/BlueLagoon.css +++ b/p/themes/BlueLagoon/BlueLagoon.css @@ -137,8 +137,6 @@ button.as-link[disabled] { .stick .btn:first-child,.stick input:first-child { border-radius: 6px 0 0 6px; } -.stick .btn-important:first-child { -} .stick .btn:last-child, .stick input:last-child { border-radius: 0 6px 6px 0; } @@ -566,11 +564,29 @@ a.btn { color: #0090FF } +/*=== Scrollbar */ + +@supports (scrollbar-width: thin) { + #sidebar { + scrollbar-color: rgba(255, 255, 255, 0.05) rgba(0, 0, 0, 0.0); + } + #sidebar:hover { + scrollbar-color: rgba(255, 255, 255, 0.3) rgba(0, 0, 0, 0.0); + } +} +@supports not (scrollbar-width: thin) { + #sidebar::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + } + #sidebar:hover::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + } +} + /*=== STRUCTURE */ /*===============*/ /*=== Header */ .header { - height: 55px; background: linear-gradient(0deg, #EDE7DE 0%, #FFF 100%) #EDE7DE; background: -webkit-linear-gradient(bottom, #EDE7DE 0%, #FFF 100%); border-bottom: solid 1px #BDB7AE; @@ -582,14 +598,14 @@ a.btn { text-align: center; } .header > .item.title .logo { - height: 60px; - width: 60px; + height: 40px; + width: 40px; } .header > .item.title{ width: 250px; } .header > .item.title h1 { - margin: 0.5em 0; + margin: 10px 0; } .header > .item.title h1 a { text-decoration: none; @@ -607,7 +623,8 @@ a.btn { /*=== Body */ #global { background:#F9F7F4; - height: calc(100% - 60px); + /* Header : 60px + 1px border bottom */ + height: calc(100% - 61px); } .aside { box-shadow: 0 2px 2px #171717 inset; diff --git a/p/themes/BlueLagoon/icons/icon.svg b/p/themes/BlueLagoon/icons/icon.svg index 8abfea179..777e85de1 100644 --- a/p/themes/BlueLagoon/icons/icon.svg +++ b/p/themes/BlueLagoon/icons/icon.svg @@ -1,5 +1,5 @@ <!-- Created with Inkscape (http://www.inkscape.org/) --> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 59.4 59.7"> <defs> <linearGradient id="linearGradient3796"> <stop stop-color="#0090ff" offset="0"/> diff --git a/p/themes/BlueLagoon/template.css b/p/themes/BlueLagoon/template.css deleted file mode 100644 index 4bc0fb735..000000000 --- a/p/themes/BlueLagoon/template.css +++ /dev/null @@ -1,696 +0,0 @@ -@charset "UTF-8"; - -/*=== GENERAL */ -/*============*/ -html, body { - margin: 0; - padding: 0; - font-size: 92%; -} - -/*=== Links */ -a { - text-decoration: none; -} -a:hover { - text-decoration: underline; -} - -/*=== Lists */ -ul, ol, dd { - margin: 0; - padding: 0; -} - -/*=== Titles */ -h1 { - margin: 0.6em 0 0.3em; - font-size: 1.5em; - line-height: 1.6em; -} -h2 { - margin: 0.5em 0 0.25em; - font-size: 1.3em; - line-height: 2em; -} -h3 { - margin: 0.5em 0 0.25em; - font-size: 1.1em; - line-height: 2em; -} - -/*=== Paragraphs */ -p { - margin: 1em 0 0.5em; - font-size: 1em; -} - -/*=== Images */ -img { - height: auto; - max-width: 100%; -} -img.favicon { - height: 16px; - width: 16px; - vertical-align: middle; -} - -/*=== Videos */ -iframe, embed, object, video { - max-width: 100%; -} - -/*=== Forms */ -legend { - display: block; - width: 100%; - clear: both; -} -label { - display: block; -} -input { - width: 180px; -} -textarea { - width: 300px; -} -input, select, textarea { - display: inline-block; - max-width: 100%; - font-size: 0.8rem; -} -input[type="radio"], -input[type="checkbox"] { - width: 15px !important; - min-height: 15px !important; -} -input.extend:focus { - width: 300px; -} - -/*=== COMPONENTS */ -/*===============*/ -/*=== Forms */ -.form-group::after { - content: ""; - display: block; - clear: both; -} -.form-group.form-actions { - min-width: 250px; -} -.form-group .group-name { - display: block; - float: left; - width: 200px; -} -.form-group .group-controls { - min-width: 250px; - margin: 0 0 0 220px; -} -.form-group .group-controls .control { - display: block; -} - -/*=== Buttons */ -.stick { - display: inline-block; - white-space: nowrap; -} -.btn, -a.btn { - display: inline-block; - cursor: pointer; - overflow: hidden; -} -.btn-important { - font-weight: bold; -} - -/*=== Navigation */ -.nav-list .nav-header, -.nav-list .item { - display: block; -} -.nav-list .item, -.nav-list .item > a { - display: block; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} -.nav-head { - display: block; -} -.nav-head .item { - display: inline-block; -} - -/*=== Horizontal-list */ -.horizontal-list { - display: table; - table-layout: fixed; - width: 100%; -} -.horizontal-list .item { - display: table-cell; -} - -/*=== Dropdown */ -.dropdown { - position: relative; - display: inline-block; -} -.dropdown-target { - display: none; -} -.dropdown-menu { - display: none; - min-width: 200px; - margin: 0; - position: absolute; - right: 0; - background: #fff; - border: 1px solid #aaa; -} -.dropdown-header { - display: block; -} -.dropdown-menu > .item { - display: block; -} -.dropdown-menu > .item > a, -.dropdown-menu > .item > span { - display: block; -} -.dropdown-menu > .item[aria-checked="true"] > a::before { - content: '✓'; -} -.dropdown-menu .input { - display: block; -} -.dropdown-menu .input select, -.dropdown-menu .input input { - display: block; - max-width: 95%; -} -.dropdown-target:target ~ .dropdown-menu { - display: block; - z-index: 10; -} -.dropdown-close { - display: inline; -} -.dropdown-close a { - font-size: 0; - position: fixed; - top: 0; bottom: 0; - left: 0; right: 0; - display: block; - z-index: -10; -} -.separator { - display: block; - height: 0; - border-bottom: 1px solid #aaa; -} - -/*=== Alerts */ -.alert { - display: block; - width: 90%; -} -.group-controls .alert { - width: 100% -} -.alert-head { - margin: 0; - font-weight: bold; -} -.alert ul { - margin: 5px 20px; -} - -/*=== Icons */ -.icon { - display: inline-block; - width: 16px; - height: 16px; - vertical-align: middle; - line-height: 16px; -} - -/*=== Pagination */ -.pagination { - display: table; - width: 100%; - margin: 0; - padding: 0; - table-layout: fixed; -} -.pagination .item { - display: table-cell; -} -.pagination .pager-first, -.pagination .pager-previous, -.pagination .pager-next, -.pagination .pager-last { - width: 100px; -} - -/*=== STRUCTURE */ -/*===============*/ -/*=== Header */ -.header { - display: table; - width: 100%; - table-layout: fixed; -} -.header > .item { - display: table-cell; -} -.header > .item.title { - width: 250px; - white-space: nowrap; -} -.header > .item.title h1 { - display: inline-block; -} -.header > .item.title .logo { - display: inline-block; - height: 32px; - width: 32px; - vertical-align: middle; -} -.header > .item.configure { - width: 100px; -} - -/*=== Body */ -#global { - display: table; - width: 100%; - height: 100%; - table-layout: fixed; -} -.aside { - display: table-cell; - height: 100%; - width: 250px; - vertical-align: top; -} -.aside.aside_flux { - background: #fff; -} - -/*=== Aside main page (categories) */ -.categories { - list-style: none; - margin: 0; -} -.category { - display: block; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} -.category .btn:not([data-unread="0"])::after { - content: attr(data-unread); -} - -/*=== Aside main page (feeds) */ -.categories .feeds { - width: 100%; - list-style: none; -} -.categories .feeds:not(.active) { - display: none; -} -.categories .feeds .feed { - display: inline-block; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - vertical-align: middle; -} -.categories .feeds .feed:not([data-unread="0"])::before { - content: "(" attr(data-unread) ") "; -} -.categories .feeds .dropdown-menu { - left: 0; -} -.categories .feeds .item .dropdown-toggle > .icon { - visibility: hidden; - cursor: pointer; - vertical-align: top; -} -.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle > .icon, -.categories .feeds .item:hover .dropdown-toggle > .icon, -.categories .feeds .item.active .dropdown-toggle > .icon { - visibility: visible; -} - -/*=== New article notification */ -#new-article { - display: none; -} -#new-article > a { - display: block; -} - -/*=== Day indication */ -.day .name { - position: absolute; - right: 0; - width: 50%; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -/*=== Feed article header and footer */ -.flux_header { - position: relative; -} -.flux .item { - line-height: 40px; - white-space: nowrap; -} -.flux .item.manage, -.flux .item.link { - width: 40px; - text-align: center; -} -.flux .item.website { - width: 200px; -} -.flux.not_read .item.title, -.flux.current .item.title { - font-weight: bold; -} -.flux:not(.current):hover .item.title { - position: absolute; - max-width: calc(100% - 320px); - background: #fff; -} -.flux .item.title a { - color: #000; - text-decoration: none; -} -.flux .item.date { - width: 145px; - text-align: right; -} -.flux .item > a { - display: block; -} -.flux .item > a { - display: block; - text-decoration: none; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; -} -.flux .item.share > a { - display: list-item; - list-style-position: inside; - list-style-type: decimal; -} - -/*=== Feed article content */ -.hide_posts > .flux:not(.active) > .flux_content { - display: none; -} -.content { - min-height: 20em; - margin: auto; - line-height: 1.7em; - word-wrap: break-word; -} -.content.large { - max-width: 1000px; -} -.content.medium { - max-width: 800px; -} -.content.thin { - max-width: 550px; -} -.content ul, -.content ol, -.content dd { - margin: 0 0 0 15px; - padding: 0 0 5px 15px; -} -.content pre { - overflow: auto; -} - -/*=== Notification and actualize notification */ -.notification { - position: absolute; - top: 1em; - left: 25%; right: 25%; - z-index: 10; - background: #fff; - border: 1px solid #aaa; -} -.notification.closed { - display: none; -} -.notification a.close { - position: absolute; - top: 0; bottom: 0; - right: 0; - display: inline-block; -} - -#actualizeProgress { - position: fixed; -} -#actualizeProgress progress { - max-width: 100%; - vertical-align: middle; -} -#actualizeProgress .progress { - vertical-align: middle; -} - -/*=== Navigation menu (for articles) */ -#nav_entries { - position: fixed; - bottom: 0; left: 0; - display: table; - width: 250px; - background: #fff; - table-layout: fixed; -} -#nav_entries .item { - display: table-cell; - width: 30%; -} -#nav_entries a { - display: block; -} - -/*=== "Load more" part */ -#load_more { - min-height: 40px; -} -.loading { - background: url("loader.gif") center center no-repeat; - font-size: 0; -} -#bigMarkAsRead { - display: block; - padding: 3em 0; - text-align: center; -} -.bigTick { - font-size: 7em; - line-height: 1.6em; -} - -/*=== Statistiques */ -.stat > table { - width: 100%; -} - -/*=== GLOBAL VIEW */ -/*================*/ -/*=== Category boxes */ -#stream.global .box-category { - display: inline-block; - width: 19em; - max-width: 95%; - margin: 20px 10px; - border: 1px solid #ccc; - vertical-align: top; -} -#stream.global .category { - width: 100%; -} -#stream.global .btn { - display: block; -} -#stream.global .box-category .feeds { - display: block; - overflow: auto; -} -#stream.global .box-category .feed { - width: 19em; - max-width: 90%; -} - -/*=== Panel */ -#overlay { - display: none; - position: fixed; - top: 0; bottom: 0; - left: 0; right: 0; - background: rgba(0, 0, 0, 0.9); -} -#panel { - display: none; - position: fixed; - top: 1em; bottom: 1em; - left: 2em; right: 2em; - overflow: auto; - background: #fff; -} -#panel .close { - position: fixed; - top: 0; bottom: 0; - left: 0; right: 0; - display: block; -} -#panel .close img { - display: none; -} - -/*=== DIVERS */ -/*===========*/ -.nav-login, -.nav_menu .search, -.nav_menu .toggle_aside { - display: none; -} - -.aside .toggle_aside { - position: absolute; - right: 0; - display: none; - width: 30px; - height: 30px; - line-height: 30px; - text-align: center; -} - -/*=== MOBILE */ -/*===========*/ -@media(max-width: 840px) { - .header, - .aside .btn-important, - .aside .feeds .dropdown, - .flux_header .item.website span, - .item.date, .day .date, - .dropdown-menu > .no-mobile, - .no-mobile { - display: none; - } - .nav-login { - display: block; - } - .nav_menu .toggle_aside, - .aside .toggle_aside, - .nav_menu .search, - #panel .close img { - display: inline-block; - } - - .aside { - position: fixed; - top: 0; bottom: 0; - left: 0; - width: 0; - overflow: hidden; - z-index: 100; - } - .aside:target { - width: 90%; - overflow: auto; - } - .aside .categories { - margin: 10px 0 75px; - } - - .flux_header .item.website { - width: 40px; - } - - .flux:not(.current):hover .item.title { - position: relative; - width: auto; - white-space: nowrap; - } - - .notification { - top: 0; - left: 0; - right: 0; - } - - #nav_entries { - width: 100%; - } - - #stream.global .box-category { - margin: 10px 0; - } - - #panel { - top: 0; bottom: 0; - left: 0; right: 0; - } - #panel .close { - top: 0; right: 0; - left: auto; bottom: auto; - display: inline-block; - width: 30px; - height: 30px; - } -} - -/*=== PRINTER */ -/*============*/ -@media print { - .header, .aside, - .nav_menu, .day, - .flux_header, - .flux_content .bottom, - .pagination, - #nav_entries { - display: none; - } - html, body { - background: #fff; - color: #000; - font-family: Serif; - } - #global, - .flux_content { - display: block !important; - } - .flux_content .content { - width: 100% !important; - } - .flux_content .content a { - color: #000; - } - .flux_content .content a::after { - content: " [" attr(href) "] "; - font-style: italic; - } -} diff --git a/p/themes/Dark/dark.css b/p/themes/Dark/dark.css index 31ff514a2..28ea253ff 100644 --- a/p/themes/Dark/dark.css +++ b/p/themes/Dark/dark.css @@ -502,6 +502,24 @@ a.btn { color: #888; } +/*=== Scrollbar */ +@supports (scrollbar-width: thin) { + #sidebar { + scrollbar-color: rgba(255, 255, 255, 0.05) rgba(0, 0, 0, 0.0); + } + #sidebar:hover { + scrollbar-color: rgba(255, 255, 255, 0.3) rgba(0, 0, 0, 0.0); + } +} +@supports not (scrollbar-width: thin) { + #sidebar::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + } + #sidebar:hover::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + } +} + /*=== STRUCTURE */ /*===============*/ /*=== Header */ diff --git a/p/themes/Flat/flat.css b/p/themes/Flat/flat.css index be047a394..1c5c3e795 100644 --- a/p/themes/Flat/flat.css +++ b/p/themes/Flat/flat.css @@ -505,6 +505,24 @@ a.btn { color: #fff; } +/*=== Scrollbar */ +@supports (scrollbar-width: thin) { + #sidebar { + scrollbar-color: rgba(255, 255, 255, 0.05) rgba(0, 0, 0, 0.0); + } + #sidebar:hover { + scrollbar-color: rgba(255, 255, 255, 0.3) rgba(0, 0, 0, 0.0); + } +} +@supports not (scrollbar-width: thin) { + #sidebar::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + } + #sidebar:hover::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + } +} + /*=== STRUCTURE */ /*===============*/ /*=== Header */ diff --git a/p/themes/Origine-compact/origine-compact.css b/p/themes/Origine-compact/origine-compact.css index 26129415a..11f3b3b25 100644 --- a/p/themes/Origine-compact/origine-compact.css +++ b/p/themes/Origine-compact/origine-compact.css @@ -167,7 +167,8 @@ form th { cursor: pointer; overflow: hidden; } -a.btn { +a.btn, +.stick .btn { min-height: 20px; line-height: 20px; } @@ -571,7 +572,7 @@ a.btn { .header > .item.search input { width: 230px; - padding: 1px 5px 0px 5px; + padding: 1px 5px; } .header .item.search input:focus { width: 350px; diff --git a/p/themes/Screwdriver/icons/icon.svg b/p/themes/Screwdriver/icons/icon.svg index 268814463..b388fa5d3 100644 --- a/p/themes/Screwdriver/icons/icon.svg +++ b/p/themes/Screwdriver/icons/icon.svg @@ -1,4 +1,4 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 57.9 58.2"> <defs> <linearGradient id="linearGradient4149"> <stop stop-color="#d18114" offset="0"/> diff --git a/p/themes/Screwdriver/screwdriver.css b/p/themes/Screwdriver/screwdriver.css index 1bc49c2db..2576c485f 100644 --- a/p/themes/Screwdriver/screwdriver.css +++ b/p/themes/Screwdriver/screwdriver.css @@ -559,6 +559,24 @@ a.btn { .tree-folder-items > .item.active > a { } +/*=== Scrollbar */ +@supports (scrollbar-width: thin) { + #sidebar { + scrollbar-color: rgba(255, 255, 255, 0.05) rgba(0, 0, 0, 0.0); + } + #sidebar:hover { + scrollbar-color: rgba(255, 255, 255, 0.3) rgba(0, 0, 0, 0.0); + } +} +@supports not (scrollbar-width: thin) { + #sidebar::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + } + #sidebar:hover::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + } +} + /*=== STRUCTURE */ /*===============*/ /*=== Header */ diff --git a/p/themes/Swage/swage.css b/p/themes/Swage/swage.css index 5cab13bd7..24a3ccbed 100644 --- a/p/themes/Swage/swage.css +++ b/p/themes/Swage/swage.css @@ -1,1211 +1,1127 @@ -textarea,input,select { -min-height:25px; -margin-top:4px; -line-height:25px; -vertical-align:middle; -background:#FCFCFC; -border:none; -padding-left:5px +textarea, input, select { +min-height: 25px; +margin-top: 4px; +line-height: 25px; +vertical-align: middle; +background: #FCFCFC; +border: none; +padding-left: 5px; } -input:invalid,select:invalid { -color:#B0425B; -border-color:#B0425B; -box-shadow:none +input:invalid, select:invalid { +color: #B0425B; +border-color: #B0425B; +box-shadow: none; } -.nav-list .nav-header,.nav-list .item { -height:2.5em; -line-height:2.5em; -font-size:.9rem +.nav-list .nav-header, .nav-list .item { +height: 2.5em; +line-height: 2.5em; +font-size: 0.9rem; } -.dropdown-menu > .item,.dropdown-menu > .item > a,.dropdown-menu > .item > span,.dropdown-menu > .item > as-link,.dropdown-menu > .item button { -padding:0 22px; -line-height:2.5em; -font-size:.8rem; -color:#FCFCFC +.dropdown-menu > .item, .dropdown-menu > .item > a, .dropdown-menu > .item > span, .dropdown-menu > .item > as-link, .dropdown-menu > .item button { +padding: 0 22px; +line-height: 2.5em; +font-size: 0.8rem; +color: #FCFCFC; } -.form-group::after,.flux::after { -content:""; -display:block; -clear:both +.form-group::after, .flux::after { +content: ""; +display: block; +clear: both; } -html,body { -height:100%; -font-family:Helvetica,Arial,sans-serif +.stick.configure-feeds, .header > .item.title, .aside, #new-article, .notification, #nav_entries { +width: 231px; } -a { -color:#00488b; -outline:none +html, body { +height: 100%; +font-family: Helvetica, Arial, sans-serif; } +a { +color: #00488b; +outline: none; +} a.btn { -min-height:25px; -line-height:25px; -text-decoration:none +min-height: 25px; +line-height: 25px; +text-decoration: none; } - a.btn:hover { -background:#00488b +background: #00488b; +} +a#btn-subscription { +width: 76%; +} +a#btn-importExport { +width: 5%; } img.icon:hover { -background:none +background: none; } div#stream { -margin-top:35px +margin-top: 35px; } sup { -top:-.3em +top: -0.3em; } legend { -display:inline-block; -width:auto; -margin:20px 0 5px; -padding:5px 20px; -font-size:1.4em; -clear:both; -background:#e3e3e3 +display: inline-block; +width: auto; +margin: 20px 0 5px; +padding: 5px 20px; +font-size: 1.4em; +clear: both; +background: #e3e3e3; } label { -min-height:25px +min-height: 25px; } textarea { -width:360px; -height:100px; -background:#e3e3e3 +width: 360px; +height: 100px; +background: #e3e3e3; } - textarea:focus { -border-color:#00488b +border-color: #00488b; } -input:focus,select:focus { -border-color:#00488b +input:focus, select:focus { +border-color: #00488b; } - -input:disabled,select:disabled { -background:#FCFCFC +input:disabled, select:disabled { +background: #FCFCFC; } select { -background:#e3e3e3 +background: #e3e3e3; } input.extend { -transition:width 200ms linear +transition: width 200ms linear; } option { -padding:0 .5em +padding: 0 .5em; } table { -border-collapse:collapse +border-collapse: collapse; } -tr,td,th { -padding:.5em; -border:1px solid #e3e3e3 +tr, td, th { +padding: 0.5em; +border: 1px solid #e3e3e3; } th { -background:#FCFCFC +background: #FCFCFC; } -form td,form th { -font-weight:400; -text-align:center +form td, form th { +font-weight: normal; +text-align: center; } .category .title.error::before { -display:inline-block; -padding-right:7px; -width:16px; -content:url(../Swage/icons/error.svg) +display: inline-block; +padding-right: 7px; +width: 16px; +content: url(../Swage/icons/error.svg); } .form-group { -padding:5px; -border:1px solid transparent +padding: 5px; +border: 1px solid transparent; } - .form-group:hover { -background:#FCFCFC; -border:1px solid #FCFCFC +background: #FCFCFC; +border: 1px solid #FCFCFC; } - .form-group.form-actions { -margin:15px 0 25px; -padding:5px 0; -background:#e3e3e3; -border-top:3px solid #e3e3e3 +margin: 15px 0 25px; +padding: 5px 0; +background: #e3e3e3; +border-top: 3px solid #e3e3e3; } - .form-group.form-actions .btn { -margin:0 10px +margin: 0 10px; } - .form-group .group-name { -padding:10px 0; -text-align:right +padding: 10px 0; +text-align: right; } - .form-group .group-controls { -min-height:25px; -padding:5px 0 +min-height: 25px; +padding: 5px 0; } - .form-group .group-controls .control { -line-height:2em +line-height: 2.0em; } - .form-group table { -margin:10px 0 0 220px +margin: 10px 0 0 220px; } .stick { -vertical-align:middle; -font-size:0 +vertical-align: middle; +font-size: 0; } .btn { -display:inline-block; -min-height:35px; -min-width:15px; -margin:0; -padding:5px 10px; -font-size:.9rem; -vertical-align:middle; -cursor:pointer; -overflow:hidden; -background:#0062be; -border:none; -color:#FCFCFC +display: inline-block; +min-height: 35px; +min-width: 15px; +margin: 0; +padding: 5px 10px; +font-size: 0.9rem; +vertical-align: middle; +cursor: pointer; +overflow: hidden; +background: #0062be; +border: none; +color: #FCFCFC; } - -.btn.active,.btn :active,.btn :hover { -background:#00488b; -text-decoration:none +.btn.active, .btn :active, .btn :hover { +background: #00488b; +text-decoration: none; } -.btn-important,.btn-attention { -font-weight:400; -background:#FA8052; -color:#FCFCFC +.btn-important, .btn-attention { +font-weight: normal; +background: #FA8052; +color: #FCFCFC; } - -.btn-important:hover,.btn-important :active,.btn-attention:hover,.btn-attention :active { -background:#f95c20!important +.btn-important:hover, .btn-important :active, .btn-attention:hover, .btn-attention :active { +background: #f95c20 !important; } .nav-list .nav-header { -padding:0 10px; -font-weight:700; -background:#22303d; -color:#FCFCFC; -cursor:default +padding: 0 10px; +font-weight: bold; +background: #22303d; +color: #FCFCFC; +cursor: default; } - -.nav-list .item:hover,.nav-list .item .active { -background:#00488b; -color:#FCFCFC +.nav-list .item:hover, .nav-list .item.active { +background: #00488b; +color: #FCFCFC; } - -.nav-list .item:hover a,.nav-list .item .active a { -color:#FCFCFC +.nav-list .item:hover a, .nav-list .item.active a { +color: #FCFCFC; } - -.nav-list .item:hover.empty a,.nav-list .item:hover .error a,.nav-list .item .active.empty a,.nav-list .item .active .error a { -color:#FCFCFC +.nav-list .item:hover.empty a, .nav-list .item:hover .error a, .nav-list .item.active.empty a, .nav-list .item.active .error a { +color: #FCFCFC; } - -.nav-list .item:hover.empty a,.nav-list .item .active.empty a { -background:#FA8052 +.nav-list .item:hover.empty a, .nav-list .item.active.empty a { +background: #FA8052; } - -.nav-list .item:hover.error a,.nav-list .item .active.error a { -background:#c46178 +.nav-list .item:hover.error a, .nav-list .item.active.error a { +background: #c46178; } - .nav-list .item > a { -padding:0 10px +padding: 0 10px; } - .nav-list .item.empty a { -color:#FA8052 +color: #FA8052; } - .nav-list .item.error a { -color:#c46178 +color: #c46178; } - .nav-list .disable { -text-align:center; -background:#FCFCFC; -color:#969696 +text-align: center; +background: #FCFCFC; +color: #969696; } - .nav-list .nav-form { -padding:3px; -text-align:center +padding: 3px; +text-align: center; } - .nav-list a:hover { -text-decoration:none +text-decoration: none; } .nav-head { -margin:0; -text-align:right; -background:#22303d; -color:#FCFCFC +margin: 0; +text-align: right; +background: #22303d; +color: #FCFCFC; } - .nav-head a { -color:#FCFCFC +color: #FCFCFC; } - .nav-head .item { -padding:5px 10px; -font-size:.9rem; -line-height:1.5rem +padding: 5px 10px; +font-size: 0.9rem; +line-height: 1.5rem; } .horizontal-list { -margin:0; -padding:0 +margin: 0; +padding: 0; } - .horizontal-list .item { -vertical-align:middle +vertical-align: middle; } .dropdown-menu { -padding:5px 0; -font-size:.8rem; -text-align:left; -border:none; -background-color:#00488b +padding: 5px 0; +font-size: 0.8rem; +text-align: left; +border: none; +background-color: #00488b; } - .dropdown-menu .dropdown-header { -cursor:default +cursor: default; } - .dropdown-menu > .item { -padding:0; -margin-left:10px +padding: 0; +margin-left: 10px; } - .dropdown-menu > .item > a { -min-width:initial; -white-space:nowrap +min-width: initial; +white-space: nowrap; } - .dropdown-menu > .item:hover { -background:#0062be; -color:#FCFCFC +background: #0062be; +color: #FCFCFC; } - .dropdown-menu > .item:hover > a { -text-decoration:none; -color:#FCFCFC +text-decoration: none; +color: #FCFCFC; } - .dropdown-menu > .item[aria-checked="true"] > a::before { -font-weight:700; -margin:0 0 0 -14px +font-weight: bold; +margin: 0 0 0 -14px; } - -.dropdown-menu .input select,.dropdown-menu .input input { -margin:0 auto 5px; -padding:2px 5px +.dropdown-menu .input select, .dropdown-menu .input input { +margin: 0 auto 5px; +padding: 2px 5px; } .dropdown-header { -padding:0 5px 5px; -font-weight:700; -text-align:left; -color:#FCFCFC +padding: 0 5px 5px; +font-weight: bold; +text-align: left; +color: #FCFCFC; } .separator { -margin:5px 0; -border-bottom:1px solid #e3e3e3; -cursor:default +margin: 5px 0; +border-bottom: 1px solid #e3e3e3; +cursor: default; } .alert { -margin:5px auto; -padding:10px 15px; -font-size:.9em; -background:#FCFCFC; -border:none; -color:#969696; -text-shadow:0 0 1px #FCFCFC +margin: 5px auto; +padding: 10px 15px; +font-size: 0.9em; +background: #FCFCFC; +border: none; +color: #969696; +text-shadow: 0 0 1px #FCFCFC; } - .alert > a { -text-decoration:underline; -color:inherit +text-decoration: underline; +color: inherit; } .alert-head { -font-size:1.15em +font-size: 1.15em; } -.alert-warn,.alert-success,.alert-error { -border:none +.alert-warn, .alert-success, .alert-error { +border: none; } .alert-warn { -background:#FCFCFC; -color:#FA8052 +background: #FCFCFC; +color: #FA8052; } .alert-success { -background:#FCFCFC; -color:#5EAABF +background: #FCFCFC; +color: #5EAABF; } .alert-error { -background:#FCFCFC; -color:#B0425B +background: #FCFCFC; +color: #B0425B; } .pagination { -text-align:center; -font-size:.8em; -background:#e3e3e3; -color:#181621 +text-align: center; +font-size: 0.8em; +background: #e3e3e3; +color: #181621; } - .pagination .item.pager-current { -font-weight:700; -font-size:1.5em; -background:#22303d; -color:#e3e3e3 +font-weight: bold; +font-size: 1.5em; +background: #22303d; +color: #e3e3e3; } - .pagination .item a { -display:block; -font-style:italic; -line-height:3em; -text-decoration:none; -color:#181621 +display: block; +font-style: italic; +line-height: 3em; +text-decoration: none; +color: #181621; } - .pagination .item a:hover { -background:#22303d; -color:#e3e3e3 +background: #22303d; +color: #e3e3e3; } - -.pagination .loading,.pagination a:hover.loading { -font-size:0; -background:url(loader.gif) center center no-repeat #22303d +.pagination .loading, .pagination a:hover.loading { +font-size: 0; +background: url(loader.gif) center center no-repeat #22303d; } .content { -padding:20px 10px +padding: 20px 10px; } - .content .pagination { -margin:0; -padding:0 +margin: 0; +padding: 0; } - .content hr { -margin:30px 10px; -height:1px; -background:#e3e3e3; -border:0; -box-shadow:0 2px 5px #e3e3e3 +margin: 30px 10px; +height: 1px; +background: #e3e3e3; +border: 0; +box-shadow: 0 2px 5px #e3e3e3; } - .content pre { -margin:10px auto; -padding:10px 20px; -overflow:auto; -background:#181621; -color:#FCFCFC; -font-size:.9rem +margin: 10px auto; +padding: 10px 20px; +overflow: auto; +background: #181621; +color: #FCFCFC; +font-size: 0.9rem; } - .content pre code { -background:transparent; -color:#FCFCFC; -border:none +background: transparent; +color: #FCFCFC; +border: none; } - .content code { -padding:2px 5px; -color:#B0425B; -background:#FCFCFC; -border:1px solid #FCFCFC +padding: 2px 5px; +color: #B0425B; +background: #FCFCFC; +border: 1px solid #FCFCFC; } - .content blockquote { -display:block; -margin:0; -padding:5px 20px; -border-top:1px solid #e3e3e3; -border-bottom:1px solid #e3e3e3; -background:#FCFCFC; -color:#969696 +display: block; +margin: 0; +padding: 5px 20px; +border-top: 1px solid #e3e3e3; +border-bottom: 1px solid #e3e3e3; +background: #FCFCFC; +color: #969696; } - .content blockquote p { -margin:0 +margin: 0; } - .content > h1.title > a { -color:#181621 +color: #181621; } .box { -border:1px solid #e3e3e3 +border: 1px solid #e3e3e3; } - .box .box-title { -margin:0; -padding:5px 10px; -background:#e3e3e3; -color:#969696; -border-bottom:1px solid #e3e3e3 +margin: 0; +padding: 5px 10px; +background: #e3e3e3; +color: #969696; +border-bottom: 1px solid #e3e3e3; } - .box .box-content { -max-height:260px +max-height: 260px; } - .box .box-content .item { -padding:0 10px; -font-size:.9rem; -line-height:2.5em +padding: 0 10px; +font-size: 0.9rem; +line-height: 2.5em; } - .box .box-content .item .configure { -visibility:hidden +visibility: hidden; } - .box .box-content .item .configure .icon { -vertical-align:middle; -background-color:#e3e3e3 +vertical-align: middle; +background-color: #e3e3e3; } - .box .box-content .item:hover .configure { -visibility:visible +visibility: visible; } - .box.category .box-title .title { -font-weight:400; -text-decoration:none; -text-align:left +font-weight: normal; +text-decoration: none; +text-align: left; } - .box.category:not([data-unread="0"]) .box-title { -background:#0062be +background: #0062be; } - .box.category:not([data-unread="0"]) .box-title:active { -background:#00488b +background: #00488b; } - .box.category:not([data-unread="0"]) .box-title .title { -font-weight:700; -color:#FCFCFC +font-weight: bold; +color: #FCFCFC; } - .box.category .title:not([data-unread="0"])::after { -position:absolute; -top:5px; -right:10px; -border:0; -background:none; -font-weight:700; -box-shadow:none; -text-shadow:none +position: absolute; +top: 5px; +right: 10px; +border: 0; +background: none; +font-weight: bold; +box-shadow: none; +text-shadow: none; } - .box.category .item.feed { -padding:2px 10px; -font-size:.8rem +padding: 2px 10px; +font-size: 0.8rem; } .tree { -margin:10px 0 +margin: 10px 0; } .tree-folder-title { -position:relative; -padding:0 10px; -background:#22303d; -line-height:2.3rem; -font-size:1rem; -height:35px +position: relative; +padding: 0 10px; +background: #22303d; +line-height: 2.3rem; +font-size: 1rem; +height: 35px; } - .tree-folder-title .title { -background:inherit; -color:#FCFCFC +background: inherit; +color: #FCFCFC; } - .tree-folder-title .title:hover { -text-decoration:none +text-decoration: none; } .tree-folder-items { -background:#22303d +background: #22303d; } - .tree-folder-items > .item { -padding:0 10px; -line-height:2.5rem; -font-size:.8rem +padding: 0 10px; +line-height: 2.5rem; +font-size: 0.8rem; } - .tree-folder-items > .item.active { -background:#00488b +background: #00488b; } - .tree-folder-items > .item > a { -text-decoration:none; -color:#FCFCFC +text-decoration: none; +color: #FCFCFC; } -.header > .item { -vertical-align:middle +@supports (scrollbar-width: thin) { + #sidebar { +scrollbar-color: rgba(255, 255, 255, 0.05) rgba(0, 0, 0, 0.0); +} +#sidebar:hover { +scrollbar-color: rgba(255, 255, 255, 0.3) rgba(0, 0, 0, 0.0); +} } -.header > .item.title { -width:231px; -position:absolute +@supports not (scrollbar-width: thin) { +#sidebar::-webkit-scrollbar-thumb { +background: rgba(255, 255, 255, 0.1); +} +#sidebar:hover::-webkit-scrollbar-thumb { +background: rgba(255, 255, 255, 0.3); +} } +.header > .item { +vertical-align: middle; +} +.header > .item.title { +position: absolute; +} .header > .item.title h1 { -margin:0; -display:block +margin: 0; +display: block; } - .header > .item.title h1 a { -text-decoration:none; -color:#FCFCFC +text-decoration: none; +color: #FCFCFC; } - .header > .item.title .logo { -display:inline-block; -height:26px; -vertical-align:top; -position:relative; -top:5px +display: inline-block; +height: 26px; +vertical-align: top; +position: relative; +top: 5px; } - .header > .item.search input { -width:230px +width: 230px; } - .header .item.search input:focus { -width:350px +width: 350px; } - .header .item.search { -display:none +display: none; } - .header .item.configure { -position:fixed; -right:0; -z-index:1000; -width:35px +position: fixed; +right: 0px; +z-index: 1000; +width: 35px; } - .header h1 { -text-align:center; -font-size:1.5em +text-align: center; +font-size: 1.5em; } .aside { -background:#22303d; -padding:35px 0; -width:231px +background: #22303d; +padding: 35px 0; } - .aside.aside_feed .tree { -margin:0 0 50px +margin: 0 0 50px; } - -.aside.aside_feed .nav-form input,.aside.aside_feed .nav-form select { -width:140px +.aside.aside_feed .nav-form input, .aside.aside_feed .nav-form select { +width: 140px; } - .aside.aside_feed .nav-form .dropdown .dropdown-menu { -right:-20px +right: -20px; } - .aside.aside_feed .nav-form .dropdown .dropdown-menu::after { -right:33px +right: 33px; } .aside_feed .tree-folder-title > .title:not([data-unread="0"])::after { -position:absolute; -right:0; -margin:6px 0; -padding:0 10px; -font-size:.9rem; -line-height:1.5rem; -background:inherit +position: absolute; +right: 0; +margin: 6px 0; +padding: 0 10px; +font-size: 0.9rem; +line-height: 1.5rem; +background: inherit; } - .aside_feed .tree-folder-items .dropdown-menu::after { -left:2px +left: 2px; } .post { -padding:10px 50px; -font-size:.9em +padding: 10px 50px; +font-size: 0.9em; } - .post input { -background:#e3e3e3 +background: #e3e3e3; +} +.post input.long { +height: 33px; +margin-top: 0px; } - .post form { -margin:10px 0 +margin: 10px 0; } - .post.content { -max-width:550px +max-width: 550px; } .prompt { -text-align:center +text-align: center; } - .prompt label { -text-align:left +text-align: left; } - .prompt form { -margin:10px auto 20px; -width:200px +margin: 10px auto 20px auto; +width: 200px; } - .prompt input { -margin:5px auto; -width:100% +margin: 5px auto; +width: 100%; } - .prompt p { -margin:20px 0 +margin: 20px 0; } #new-article { -text-align:center; -font-size:1em; -background:#0062be; -position:fixed; -bottom:48px; -z-index:900; -left:0; -width:231px; -line-height:1.5em +text-align: center; +font-size: 1em; +background: #0062be; +position: fixed; +bottom: 48px; +z-index: 900; +left: 0; +line-height: 1.5em; } - #new-article:hover { -background:#00488b +background: #00488b; } - #new-article > a { -line-height:1.5em; -font-weight:700; -color:#FCFCFC +line-height: 1.5em; +font-weight: bold; +color: #FCFCFC; } - #new-article > a:hover { -text-decoration:none +text-decoration: none; } .day { -padding:0 10px; -font-weight:700; -line-height:3em; -text-align:center +padding: 0 10px; +font-weight: bold; +line-height: 3em; +text-align: center; } - .day .name { -display:none +display: none; } .nav a { -color:#FCFCFC +color: #FCFCFC; } .nav_menu { -font-size:0; -background-color:#0062be; -position:fixed; -width:100%; -z-index:900 +font-size: 0; +background-color: #0062be; +position: fixed; +width: 100%; +z-index: 900; } - .nav_menu .item.search { -display:inline-block; -position:fixed; -right:40px +display: inline-block; +position: fixed; +right: 40px; } .flux { -padding-right:10px; -background:#FCFCFC +padding-right: 10px; +background: #FCFCFC; } - .flux::after { -margin:0 auto; -width:90%; -border-top:1px solid #e3e3e3 +margin: 0 auto; +width: 90%; +border-top: 1px solid #e3e3e3; } - -.flux:hover,.flux .current { -background:#FFF +.flux:hover, .flux .current { +background: #FFFFFF; } - -.flux:hover:not(.current):hover .item.title,.flux .current:not(.current):hover .item.title { -background:#FFF +.flux:hover:not(.current):hover .item.title, .flux .current:not(.current):hover .item.title { +background: #FFFFFF; } - .flux.not_read { -background:#FFF3ED +background: #FFF3ED; } - .flux.not_read:not(.current):hover .item.title { -background:#FFF3ED +background: #FFF3ED; } - .flux.favorite { -background:#FFF6DA +background: #FFF6DA; } - .flux.favorite:not(.current):hover .item.title { -background:#FFF6DA +background: #FFF6DA; } - .flux .date { -font-size:.7rem; -color:#969696 +font-size: 0.7rem; +color: #969696; } - .flux .bottom { -font-size:.8rem; -text-align:center +font-size: 0.8rem; +text-align: center; } - .flux .website .favicon { -padding:5px +padding: 5px; } - .flux label { -color:#FCFCFC; -cursor:pointer +color: #FCFCFC; +cursor: pointer; } .flux_header { -font-size:.8rem; -cursor:pointer +font-size: 0.8rem; +cursor: pointer; } - .flux_header .title { -font-size:.9rem +font-size: 0.9rem; } .notification { -text-align:center; -font-weight:700; -font-size:1em; -padding:10px 0; -z-index:10; -vertical-align:middle; -background:#e3e3e3; -color:#969696; -border:none; -position:fixed; -bottom:48px; -left:0; -top:auto; -width:231px; -height:auto -} - -.notification.good,.notification .bad { -color:#FCFCFC +text-align: center; +font-weight: bold; +font-size: 1em; +padding: 10px 0; +z-index: 10; +vertical-align: middle; +background: #e3e3e3; +color: #969696; +border: none; +position: fixed; +bottom: 48px; +left: 0; +top: auto; +height: auto; +} +.notification.good, .notification .bad { +color: #FCFCFC; } - .notification.good { -background:#5EAABF +background: #5EAABF; } - .notification.good a.close:hover { -background:#5EAABF +background: #5EAABF; } - .notification.bad { -background:#c46178 +background: #c46178; } - .notification.bad a.close:hover { -background:#c46178 +background: #c46178; } - .notification#actualizeProgress { -line-height:2em +line-height: 2em; } - .notification a.close { -display:none +display: none; } #bigMarkAsRead { -text-align:center; -text-decoration:none; -background:#e3e3e3; -padding:20px!important +text-align: center; +text-decoration: none; +background: #e3e3e3; } - #bigMarkAsRead:hover { -background:#22303d; -color:#FCFCFC +background: #22303d; +color: #FCFCFC; } #nav_entries { -margin:0; -text-align:center; -line-height:3em; -table-layout:fixed; -width:231px; -background:#22303d +margin: 0; +text-align: center; +line-height: 3em; +table-layout: fixed; +background: #22303d; } .stat { -margin:10px 0 20px +margin: 10px 0 20px; +} +.stat th, .stat td, .stat tr { +border: none; +} +.stat > table td, .stat > table th { +border-bottom: 1px solid #e3e3e3; +} +.stat > .horizontal-list { +margin: 0 0 5px; +} +.stat > .horizontal-list .item { +overflow: hidden; +white-space: nowrap; +text-overflow: ellipsis; +} +.stat > .horizontal-list .item:first-child { +width: 270px; } -.stat th,.stat td,.stat tr { -border:none +.formLogin #global { +height: 0; } -.stat > table td,.stat > table th { -border-bottom:1px solid #e3e3e3 +.formLogin .header { +height: 55px; +background: #22303d; } -.stat > .horizontal-list { -margin:0 0 5px +.formLogin .header > .item.configure { +width: 200px; +position: unset; } -.stat > .horizontal-list .item { -overflow:hidden; -white-space:nowrap; -text-overflow:ellipsis +.formLogin a.signin { + color: #FCFCFC; + padding-left: 5px; } -.stat > .horizontal-list .item:first-child { -width:270px +.formLogin .header > .item.title h1 { + display: unset; +} + +.formLogin input { + border-left: 5px solid; + border-right: 1px solid #e3e3e3; + border-top: 1px solid #e3e3e3; + border-bottom: 1px solid #e3e3e3; } .loglist { -overflow:hidden; -border:1px solid #969696 +overflow: hidden; +border: 1px solid #969696; } .log { -padding:5px 2%; -overflow:auto; -font-size:.8rem; -background:#FCFCFC +padding: 5px 2%; +overflow: auto; +font-size: 0.8rem; +background: #FCFCFC; } - .log > .date { -margin:0 10px 0 0; -padding:5px 10px +margin: 0 10px 0 0; +padding: 5px 10px; } - .log.error > .date { -background:#c46178; -color:#FCFCFC +background: #c46178; +color: #FCFCFC; } - .log.warning > .date { -background:#FA8052; -color:#FCFCFC +background: #FA8052; +color: #FCFCFC; } - .log.notice > .date { -background:#e3e3e3; -color:#FCFCFC +background: #e3e3e3; +color: #FCFCFC; } - .log.debug > .date { -background:#181621; -color:#FCFCFC +background: #181621; +color: #FCFCFC; } @media (max-width: 840px) { -.dropdown-header,.dropdown-menu > .item { -padding:12px +.formLogin .header { +display: none; +} + +.dropdown-header, .dropdown-menu > .item { +padding: 12px; } #new-article { -width:100%; -bottom:initial +width: 100%; +bottom: initial; } .header { -display:table +display: table; } - .header .item.title .logo { -display:none +display: none; } .header > .item.title h1 a { -display:block; -position:absolute; -top:-35px; -left:10px; -font-size:.6em +display: block; +position: absolute; +top: -35px; +left: 10px; +font-size: 0.6em; } -.header .item.configure,button.read_all.btn { -display:none +.header .item.configure, button.read_all.btn { +display: none; } -.flux .item.manage,.flux_header .item.website { -width:35px; -text-align:center +.flux .item.manage, .flux_header .item.website { +width: 35px; +text-align: center; } .aside { -width:0; -transition:width 200ms linear +width: 0; +transition: width 200ms linear; } - .aside .toggle_aside { -display:block; -height:50px; -line-height:50px; -text-align:right; -padding-right:10px; -background:#22303d +display: block; +height: 50px; +line-height: 50px; +text-align: right; +padding-right: 10px; +background: #22303d; } - .aside.aside_feed { -padding:0 +padding: 0; } - .aside:target { -width:78% +width: 78%; } .nav_menu { -position:initial; -height:71px +position: initial; +height: 71px; } - .nav_menu .btn { -margin:5px 10px +margin: 5px 10px; } - .nav_menu .stick { -margin:0 10px +margin: 0 10px; } - .nav_menu .stick .btn { -margin:5px 0 +margin: 5px 0; } - .nav_menu .search { -position:absolute!important; -top:35px; -left:55px +position: absolute !important; +top: 35px; +left: 55px; } - .nav_menu .search input { -width:85% +width: 85%; } .pagination { -margin:0 0 3.5em +margin: 0 0 3.5em; } #panel .close { -display:block; -height:50px; -line-height:50px; -text-align:right; -padding-right:10px; -background:#22303d +display: block; +height: 50px; +line-height: 50px; +text-align: right; +padding-right: 10px; +background: #22303d; } .day .name { -font-size:1.1rem +font-size: 1.1rem; } .notification { -width:100% +width: 100%; } - .notification a.close { -display:block; -left:0; -background:transparent +display: block; +left: 0; +background: transparent; } - .notification a.close:hover { -opacity:.5 +opacity: 0.5; } - .notification a.close .icon { -display:none +display: none; } #nav_entries { -width:100%!important +width: 100% !important; } div#stream { -margin-top:0 +margin-top: 0px; } a.btn.toggle_aside { -position:absolute; -top:29px +position: absolute; +top: 29px; } -form#mark-read-menu,a#actualize,a#toggle-order,div#nav_menu_actions,div#nav_menu_views { -position:absolute +form#mark-read-menu, a#actualize, a#toggle-order, div#nav_menu_actions, div#nav_menu_views { +position: absolute; } form#mark-read-menu { -right:46px; -top:30px; -z-index:1100 +right: 46px; +top: 30px; +z-index: 1100; } -a#actualize,a#toggle-order { -right:0 +a#actualize, a#toggle-order { +right: 0px; } a#actualize { -top:29px +top: 29px; } -a#toggle-order,div#nav_menu_actions,div#nav_menu_views { -top:65px +a#toggle-order, div#nav_menu_actions, div#nav_menu_views { +top: 65px; } div#nav_menu_actions { -left:0 +left: 0px; } div#nav_menu_views { -right:50px +right: 50px; } } - @media (max-width: 410px) { .nav_menu .stick { -margin:0 +margin: 0; } } - @media (max-width: 374px) { #nav_menu_views { -display:none +display: none; } } - button.as-link { -color:#FCFCFC; -outline:none +color: #FCFCFC; +outline: none; } .dropdown-target:target ~ .btn.dropdown-toggle { -background:#00488b +background: #00488b; } .tree-folder.active .tree-folder-title { -background:#00488b; -font-weight:700 +background: #00488b; +font-weight: bold; } .feed.item.empty { -color:#FA8052 +color: #FA8052; } - .feed.item.empty.active { -background:#FA8052; -color:#FCFCFC +background: #FA8052; +color: #FCFCFC; } - .feed.item.empty.active > a { -color:#FCFCFC +color: #FCFCFC; } - .feed.item.empty > a { -color:#FA8052 +color: #FA8052; } - .feed.item.error { -color:#c46178 +color: #c46178; } - .feed.item.error.active { -background:#c46178; -color:#FCFCFC +background: #c46178; +color: #FCFCFC; } - .feed.item.error.active > a { -color:#FCFCFC +color: #FCFCFC; } - .feed.item.error > a { -color:#c46178 +color: #c46178; } #dropdown-query ~ .dropdown-menu .dropdown-header .icon { -vertical-align:middle; -float:right +vertical-align: middle; +float: right; } #stream.reader .flux { -padding:0 0 50px; -background:#FCFCFC; -color:#22303d; -border:none +padding: 0 0 50px; +background: #FCFCFC; +color: #22303d; +border: none; } - #stream.reader .flux .author { -margin:0 0 10px; -font-size:90%; -color:#969696 +margin: 0 0 10px; +font-size: 90%; +color: #969696; } -#nav_menu_actions ul.dropdown-menu,#nav_menu_read_all ul.dropdown-menu { -left:0 +#nav_menu_actions ul.dropdown-menu, #nav_menu_read_all ul.dropdown-menu { +left: 0px; } #slider label { -min-height:initial +min-height: initial; } - #slider .form-group:hover { -background:inital -}
\ No newline at end of file +background: inital; +} diff --git a/p/themes/Swage/swage.scss b/p/themes/Swage/swage.scss index 9bd0326d9..ecacba832 100644 --- a/p/themes/Swage/swage.scss +++ b/p/themes/Swage/swage.scss @@ -12,6 +12,7 @@ $color_stared: #FFF6DA; $color_unread: #FFF3ED; $color_hover: #FFFFFF; + // @extend-elements %input { min-height: 25px; @@ -48,6 +49,10 @@ $color_hover: #FFFFFF; clear: both; } +%aside-width { + width: 231px; +} + // /@extend-elements html, body { @@ -66,6 +71,12 @@ a { background: darken( $color_nav, 10%); } } + &#btn-subscription { + width: 76%; + } + &#btn-importExport { + width: 5%; + } } img { @@ -205,6 +216,9 @@ form { .stick { vertical-align: middle; font-size: 0; + &.configure-feeds { + @extend %aside-width; + } } .btn { @@ -250,7 +264,7 @@ form { .item { @extend %nav-list; &:hover, - .active { + &.active { background: darken( $color_nav, 10%); color: $color_light; a { @@ -337,7 +351,7 @@ form { > a { min-width: initial; white-space: nowrap; - } + } &:hover { background: $color_nav; color: $color_light; @@ -589,11 +603,29 @@ form { } } +@supports (scrollbar-width: thin) { + #sidebar { + scrollbar-color: rgba(255, 255, 255, 0.05) rgba(0, 0, 0, 0.0); + } + #sidebar:hover { + scrollbar-color: rgba(255, 255, 255, 0.3) rgba(0, 0, 0, 0.0); + } +} + +@supports not (scrollbar-width: thin) { + #sidebar::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + } + #sidebar:hover::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + } +} + .header { > .item { vertical-align: middle; &.title { - width: 231px; + @extend %aside-width; position: absolute; h1 { margin: 0; @@ -636,7 +668,7 @@ form { .aside { background: $color_aside; padding: 35px 0; - width: 231px; + @extend %aside-width; &.aside_feed { .tree { margin: 0 0 50px; @@ -678,6 +710,10 @@ form { font-size: 0.9em; input { background: darken( $color_light, 10% ); + &.long{ + height: 33px; + margin-top: 0px; + } } form { margin: 10px 0; @@ -713,7 +749,7 @@ form { bottom: 48px; z-index: 900; left: 0; - width: 231px; + @extend %aside-width; line-height: 1.5em; &:hover { background: darken( $color_nav, 10%); @@ -825,7 +861,7 @@ form { bottom: 48px; left: 0; top: auto; - width: 231px; + @extend %aside-width; height: auto; &.good, .bad { @@ -855,7 +891,6 @@ form { text-align: center; text-decoration: none; background: darken( $color_light, 10%); - padding: 20px !IMPORTANT; &:hover { background: $color_aside; color: $color_light; @@ -867,7 +902,7 @@ form { text-align: center; line-height: 3em; table-layout: fixed; - width: 231px; + @extend %aside-width; background: $color_aside; } @@ -897,6 +932,37 @@ form { } } +.formLogin { + #global { + height: 0; + } + + .header { + height: 55px; + background: $color_aside; + > .item { + &.configure { + width: 200px; + position: unset; + } + &.title h1 { + display: unset; + } + } + } + a.signin { + color: $color_light; + padding-left: 5px; + } + + input { + border-left: 5px solid; + border-right: 1px darken( $color_light, 10%); + border-top: 1px darken( $color_light, 10%); + border-bottom: 1px darken( $color_light, 10%); + } +} + .loglist { overflow: hidden; border: 1px solid darken( $color_light, 40% ); @@ -930,10 +996,13 @@ form { } @media(max-width: 840px) { + .formLogin .header { + display: none; + } .dropdown-header, .dropdown-menu > .item { padding: 12px; } - + #new-article { width: 100%; bottom: initial; @@ -1156,5 +1225,5 @@ button.as-link { background: inital; } } - -}
\ No newline at end of file + +} diff --git a/p/themes/base-theme/template.css b/p/themes/base-theme/template.css index b211d0516..099aee916 100644 --- a/p/themes/base-theme/template.css +++ b/p/themes/base-theme/template.css @@ -109,7 +109,7 @@ input[type="checkbox"] { min-height: 15px !important; } .dropdown-menu label > input[type="text"] { - with: 150px; + width: 150px; width: calc(99% - 5em); } .dropdown-menu input[type="checkbox"] { @@ -143,7 +143,7 @@ td.numeric { /*===============*/ [aria-hidden="true"] { - display: none; + display: none !important; } /*=== Forms */ @@ -168,6 +168,13 @@ td.numeric { display: block; } +@supports (position: sticky) { + #mark-read-aside { + position: sticky; + top: 0; + } +} + /*=== Buttons */ .stick { display: inline-block; @@ -230,6 +237,11 @@ a.btn { background: #fff; border: 1px solid #aaa; } +.dropdown-menu-scrollable { + max-height: 75vh; + overflow-x: hidden; + overflow-y: auto; +} .dropdown-header { display: block; } @@ -256,7 +268,7 @@ a.btn { } .dropdown-target:target ~ .dropdown-menu { display: block; - z-index: 10; + z-index: 1000; } .dropdown-close { display: inline; @@ -268,6 +280,7 @@ a.btn { left: 0; right: 0; display: block; z-index: -10; + cursor: default; } .separator { display: block; @@ -368,16 +381,40 @@ a.btn { cursor: grab; } +/*=== Scrollbar */ +@supports (scrollbar-width: thin) { + #sidebar { + overflow-y: auto; + scrollbar-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.05); + scrollbar-width: thin; + } + #sidebar:hover { + scrollbar-color: rgba(0, 0, 0, 0.3) rgba(0, 0, 0, 0.05); + } +} + +@supports not (scrollbar-width: thin) { + #sidebar::-webkit-scrollbar { + background: rgba(0, 0, 0, 0.05); + width: 8px; + } + #sidebar::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.1); + border-radius: 5px; + display: unset; + } + #sidebar:hover::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.3); + } +} + /*=== Tree */ .tree { margin: 0; - padding: 0 0 2em 0; + max-height: 99vh; list-style: none; text-align: left; -} - -.treepadding { - padding: 0 0 15em 0; + overflow-x: hidden; } .tree-folder-items { @@ -407,6 +444,10 @@ a.btn { white-space: nowrap; text-overflow: ellipsis; } +.tree-bottom { + visibility: hidden; + margin-bottom: 18em; +} /*=== STRUCTURE */ /*===============*/ @@ -445,7 +486,6 @@ a.btn { } .aside { display: table-cell; - height: 100%; width: 300px; vertical-align: top; } @@ -667,6 +707,21 @@ br + br + br { height: 300px; } +/*=== LOGIN VIEW */ +/*================*/ +.formLogin .header > .item { + padding: 10px 30px; +} + +.formLogin .header > .item.title { + text-align: left; +} + +.formLogin .header > .item.configure { + text-align: right; +} + + /*=== GLOBAL VIEW */ /*================*/ #stream.global { @@ -854,6 +909,29 @@ pre.enclosure-description { white-space: pre-line; } +/*=== READER */ +/*===========*/ +.reader .nav_menu .toggle_aside { + display: inline-block; +} + +.reader .aside .toggle_aside { + display: block; + width: 100%; +} + +.reader .aside { + width: 0; +} + +.reader .aside:target { + width: 300px; +} + +.reader .aside .stick { + display: none; +} + /*=== MOBILE */ /*===========*/ @media(max-width: 840px) { @@ -894,7 +972,6 @@ pre.enclosure-description { } .aside:target { width: 90%; - overflow: auto; } .flux_header .item.website { |
