Compare commits

..

76 Commits

Author SHA1 Message Date
14044c99c0 Test with old command 2016-03-12 11:49:24 +01:00
df3f45d4d0 Update travis configuration for releasing 2016-03-12 11:33:37 +01:00
6c9bb06393 Release wallabag 2.0.0-beta.2 2016-03-12 11:20:38 +01:00
6ab56c7b2c Merge pull request #1775 from wallabag/v2-few-fixes
Some fixes
2016-03-12 11:10:21 +01:00
b95ffda2a1 Fix hazardous bug with Postgres
Instead of retrieving a random annotation, sort them to be sure they are all the same no matter the database used
2016-03-12 10:45:14 +01:00
55e61971f3 Merge pull request #1776 from wallabag/v2-doc-clarify-php7
clarify that wllbg is compatible php 7
2016-03-11 20:39:48 +01:00
d6dba929a1 clarify that wllbg is compatible php 7 2016-03-11 20:14:14 +01:00
09d8bb6fa2 Improve tests
- add more tests for coverage
- add a test on annotation deletion
- fix post annontation with ranges
2016-03-11 17:59:42 +01:00
66e2be2371 Use --prefer-dist to improve CI perf
https://twitter.com/seldaek/status/708236348281495552
2016-03-11 17:59:42 +01:00
6aed6d69a5 Merge pull request #1763 from wallabag/v2-prepare-beta2
Prepare files for 2.0.0-beta.2
2016-03-11 13:43:57 +01:00
c118131317 git clone with prefer-dist option 2016-03-10 13:04:56 +01:00
24c16007bb Finally back to composer create-project but with --keep-vcs option 2016-03-10 12:43:03 +01:00
4c51979595 Add -o option in composer install command 2016-03-10 12:43:03 +01:00
0f4e919100 French documentation for new installation 2016-03-10 12:43:03 +01:00
83be3dc097 Prepare files for 2.0.0-beta.2 2016-03-10 12:43:03 +01:00
e7931dbdf8 Merge pull request #1771 from wallabag/docker-timezone
Docker timezone
2016-03-09 10:42:15 +01:00
b80841f23c Add comment about timezone definition 2016-03-09 09:04:31 +01:00
612f5f1ec7 Add the timezone as an argument in the docker-compose.
For that, need to use v2 of docker-compose (with version >= 1.6.0)
2016-03-09 09:04:19 +01:00
125460345f Add the timezone for PHP docker container 2016-03-09 09:02:06 +01:00
d460a7377a Merge pull request #1766 from wallabag/v2-add-wallabag-in-title
Fix #1756: Added 'wallabag' in page title
2016-03-08 15:49:13 +01:00
cebb42234c Added 'wallabag' in page title 2016-03-08 15:22:35 +01:00
f4109a9bbf Merge pull request #1762 from wallabag/v2-fix-quickstart-links
Change documentation links in quickstart
2016-03-08 12:00:59 +01:00
3b32c122ab Change documentation links in quickstart 2016-03-08 11:21:40 +01:00
d442cf4a92 Merge pull request #1761 from wallabag/v2-API-version
V2 api version
2016-03-08 10:09:57 +01:00
807037884f Merge pull request #1675 from wallabag/v2-create-api-client
Ability to create new client for the API
2016-03-08 10:09:39 +01:00
6f8310b445 typos & cs 2016-03-08 09:22:25 +01:00
9761bfa18e write test for version 2016-03-07 15:16:27 +01:00
2b4770301c Add version in API 2016-03-07 15:00:03 +01:00
d11eb2e461 Fix translations mistake
In Material template, move the developer link in the left menu (like in baggy)
2016-03-07 11:05:14 +01:00
f17281417c Translate "how to" page 2016-03-07 09:20:20 +01:00
2766668b59 Use external js & css 2016-03-07 08:58:08 +01:00
1256f6fe34 Add translations 2016-03-05 22:29:58 +01:00
9bf15f0269 Add listing clients
Rename route to be more consistive (ie: prefixed with developer_)
2016-03-05 21:44:39 +01:00
2c2308b783 Cleanup form
- Avoid too much hidden data in the form (instead of manually define the submit button and hide the default, use the default one !)
- Fix HTML syntax in client_parameters
- Add developer link in baggy menu
- Fix space between link in material footer
2016-03-05 20:04:19 +01:00
1e5a4b36ab Update filters picture in documentation 2016-03-04 16:20:04 +01:00
e68568cd5b Merge pull request #1750 from wallabag/v2-quickstart-documentation
Documentation about filters / Quickstart changes
2016-03-04 16:14:39 +01:00
d89908aed3 Merge pull request #1670 from wallabag/v2-mark-imported-articles-as-read
Mark all imported articles as read
2016-03-04 16:12:45 +01:00
e166a58fd9 update picture 2016-03-04 15:45:45 +01:00
e18138dbca Merge pull request #1754 from wallabag/v2-api-new-properties-light
Add starred & archive properties to API
2016-03-04 12:31:27 +01:00
fba9e7d44d Remove 'content' from API
Waiting to find a good solution to avoid side problem since user can no define the content
2016-03-04 11:46:18 +01:00
11a452813c use booleans instead of empty 2016-03-04 11:39:21 +01:00
816ad4051b add more properties for entries #1634 2016-03-04 11:39:20 +01:00
79d0e38e7f Adding test
Reformat json file (thanks pro.jsonlint.com)
2016-03-04 10:04:51 +01:00
9e3355ee4f Merge pull request #1753 from Horgix/v2-typo-doc-en
Doc: fix typo in php-hash ext name
2016-03-04 06:17:19 +01:00
5dfd321d0e Doc: fix typo in php-hash ext name 2016-03-04 01:07:45 +01:00
c32ae320fe cs & tests for wllbg v1 import 2016-03-03 10:03:40 +01:00
c10fcb3bbb french translation & pocket 2016-03-03 10:03:40 +01:00
fe8b37c137 Mark all imported articles as read 2016-03-03 10:03:28 +01:00
3d15ea2fd7 Documentation about filters (and some fixes in french documentation 2016-03-03 08:06:18 +01:00
76a9bc4797 Add new links in quickstart 2016-03-03 07:30:05 +01:00
7d12fd0628 Merge pull request #1745 from benages/v2
V2 spanish translation
2016-03-02 09:06:46 +01:00
e5f3b04cce Spanish translation 2016-03-01 23:26:03 +01:00
3ca529970c Spanish translation 2016-03-01 22:36:21 +01:00
9931a37cf7 Spanish translation 2016-03-01 22:33:55 +01:00
348e2b4852 Spanish translation 2016-03-01 22:24:34 +01:00
bd5b3ea8ea Spanish translation 2016-03-01 22:20:42 +01:00
9c5cfd2823 Merge remote-tracking branch 'upstream/v2' into v2 2016-03-01 21:02:13 +01:00
0e576d2163 Start of the spanish translation 2016-03-01 21:00:35 +01:00
646df062df Merge pull request #1743 from wallabag/v2-releasing-documentation
Releasing documentation
2016-03-01 20:49:54 +01:00
6b6f725182 Add steps in RELEASE_PROCESS 2016-03-01 20:21:18 +01:00
461a171467 Releasing documentation 2016-03-01 20:10:26 +01:00
f8b835f537 Merge pull request #1615 from bdunogier/release_process_doc
Added RELEASE_PROCESS document
2016-03-01 20:06:44 +01:00
df814148c3 Merge pull request #1740 from goofy-bz/patch-6
minor typofix again
2016-03-01 17:00:49 +01:00
7b70feb9d2 fixing previous stuff and more 2016-03-01 16:12:15 +01:00
9adfede511 minor fix
adding non-breaking spaces here and there + small piece of translation and relevant French link
2016-03-01 16:09:50 +01:00
244ee24764 Merge pull request #1742 from wallabag/v2-issue-template-package
Add the way to install (package or composer)
2016-03-01 13:23:39 +01:00
a6a971d45f Add the way to install (package or composer) 2016-03-01 12:01:42 +01:00
c273b3a5c1 minor typofix again 2016-02-29 22:04:32 +01:00
5bf8f3f164 Remove comments 2016-02-29 21:28:37 +01:00
5bc2da5628 Add password for auth 2016-02-29 21:28:25 +01:00
8a4690b6a5 add tests 2016-02-29 21:28:25 +01:00
abc329453b Enhance documentation and create a form to create a new client 2016-02-29 21:28:25 +01:00
6a2c524a2c API: rename application to client 2016-02-29 21:28:25 +01:00
b6321bed7b Added developer documentation 2016-02-29 21:28:25 +01:00
24152cdb5e Fix #1597: first draft to create new client for the API 2016-02-29 21:28:25 +01:00
923a7e8d68 Added RELEASE_PROCESS document 2016-02-27 23:32:26 +01:00
62 changed files with 1763 additions and 179 deletions

View File

@ -6,6 +6,7 @@ Remember, this is _not_ a place to ask questions. For that, go to http://gitter.
### Environment
* wallabag version (or git revision) that exhibits the issue:
* How did you install wallabag? Via `composer create-project` or by downloading the package?
* Last wallabag version that did not exhibit the issue (if applicable):
* php version:
* OS:

View File

@ -11,12 +11,16 @@ More informations on our website: [wallabag.org](https://wallabag.org)
# Want to test the v2?
Keep in mind it's an **unstable** branch, everything can be broken :)
If you don't have it yet, please [install composer](https://getcomposer.org/download/). Then you can install wallabag by executing the following commands:
If you don't have it yet, please [install composer](https://getcomposer.org/download/).
Then you can install wallabag by executing the following commands:
```
SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.0-beta.1" --no-dev
php bin/console wallabag:install --env=prod
php bin/console server:run --env=prod
git clone https://github.com/wallabag/wallabag.git
cd wallabag
git checkout 2.0.0-beta.2
SYMFONY_ENV=prod composer install --no-dev -o --prefer-dist
php bin/console wallabag:install --env=prod
php bin/console server:run --env=prod
```
## License

67
RELEASE_PROCESS.md Normal file
View File

@ -0,0 +1,67 @@
## Definition
A release is mostly a git tag of http://github.com/wallabag/wallabag, following [semantic versioning](http://semver.org).
The last release at the time of writing is 2.0.0-alpha.2, from the v2 branch.
### Steps to release
During this documentation, we assume the release is `release-2.0.0-beta.1`.
#### Files to edit
- `app/config/config.yml` (`wallabag_core.version`)
- `README.md` (`composer create-project` command)
- `docs/en/user/installation.rst` and its translations (`composer create-project` command)
#### Create release on GitHub
- Run these commands to create the tag:
```
git checkout v2
git pull origin v2
git checkout -b release-2.0.0-beta.1
SYMFONY_ENV=prod composer up --no-dev
git add --force composer.lock
git add README.md
git commit -m "Release wallabag 2.0.0-beta.1"
git push origin release-2.0.0-beta.1
```
- Create a new pull request with this title `DON'T MERGE Release wallabag 2.0.0-beta.1`. This pull request is used to launch builds on Travis-CI.
- Run these commands to create the package:
```
git clone git@github.com:wallabag/wallabag.git -b release-2.0.0-beta.1 release-2.0.0-beta.1
SYMFONY_ENV=prod composer up -d=release-2.0.0-beta.1 --no-dev
tar czf wallabag-release-2.0.0-beta.1.tar.gz --exclude="var/*" --exclude=".git" release-2.0.0-beta.1
```
- [Create the new release on GitHub](https://github.com/wallabag/wallabag/releases/new). You have to upload on this page the package.
- Delete the `release-2.0.0-beta.1` branch and close the pull request (**DO NOT MERGE IT**).
- Update the URL shortener (used on `wllbg.org` to generate links like `http://wllbg.org/latest-v2-package` or `http://wllbg.org/latest-v2`)
- Update [the downloads page](https://github.com/wallabag/wallabag.org/blob/master/content/pages/download.md) on the website (MD5 sum, release date)
- Drink a beer!
### `composer.lock`
A release tag must contain a `composer.lock` file. It sets which dependencies were available at the time a release was done,
making it easier to fix issues after the release. It also speeds up `composer install` on stable versions a LOT, by skipping the
dependencies resolution part.
Since `composer.lock` is ignored by default, either it must be removed from `.gitignore` _in the release branch_,
or it must be added using `git add --force composer.lock`.
### Target PHP version
`composer.lock` is _always_ built for a particular version, by default the one it is generated (with `composer update`).
If the PHP version used to generate the .lock isn't a widely available one (like PHP 7), a more common one should
be locally specified in `composer.lock`:
```json
"config": {
"platform": {
"php": "5.5.9",
"ext-something": "4.0"
}
}
```

View File

@ -0,0 +1,29 @@
download_pictures: Descagar imagenes
carrot: Activar compartir con Carrot
diaspora_url: Diaspora URL, si el servicio esta activado
export_epub: Activar exportación a ePub
export_mobi: Activar exportación a .mobi
export_pdf: Activar exportación a PDF
export_csv: Activar exportación a CSV
export_json: Activar exportación a JSON
export_txt: Activar exportación a TXT
export_xml: Activar exportación a XML
pocket_consumer_key: Consumer key for Pocket to import contents (https://getpocket.com/developer/docs/authentication)
shaarli_url: Shaarli URL, si el servicio está activado
share_diaspora: Activar compartir con Diaspora
share_mail: Activar compartir con email
share_shaarli: Activar compartir con Shaarli
share_twitter: Activar compartir con Twitter
show_printlink: Mostrar un link para imprimir contenido
wallabag_support_url: URL de soporte de wallabag
wallabag_url: URL de *tu* instancia de wallabag
entry: "artículo"
export: "exportar"
import: "importar"
misc: "misc"
modify_settings: "modificar configuración"
piwik_host: Host de tu website de Piwik
piwik_site_id: ID de tu website de Piwik
piwik_enabled: Activar Piwik
demo_mode_enabled: "Activar modo demo (sólo usado para la demo de wallabag)"
demo_mode_username: "Nombre de usuario demo"

View File

@ -0,0 +1,2 @@
Login: "Logearse"
Enter your email address below and we'll send you password reset instructions.: "Introduzca su dirección de email y le enviaremos las instrucciones para resetear su contraseña."

View File

@ -28,7 +28,7 @@ framework:
assets: ~
wallabag_core:
version: 2.0.0-beta.1
version: 2.0.0-beta.2
paypal_url: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9UBA65LG3FX9Y&lc=gb"
languages:
en: 'English'
@ -39,6 +39,7 @@ wallabag_core:
ro: 'Română'
pl: 'Polish'
da: 'Dansk'
es: 'Español'
items_on_page: 12
theme: material
language: en

View File

@ -53,6 +53,7 @@ security:
access_control:
- { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/version, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

147
composer.lock generated
View File

@ -1266,12 +1266,12 @@
"source": {
"type": "git",
"url": "https://github.com/FriendsOfSymfony/FOSUserBundle.git",
"reference": "e770bfa2fd0fc665f55cd7cfeb34bddeffb892f4"
"reference": "16b04c49af05dd3fb381e4abe04f0e5e231ac76d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/e770bfa2fd0fc665f55cd7cfeb34bddeffb892f4",
"reference": "e770bfa2fd0fc665f55cd7cfeb34bddeffb892f4",
"url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/16b04c49af05dd3fb381e4abe04f0e5e231ac76d",
"reference": "16b04c49af05dd3fb381e4abe04f0e5e231ac76d",
"shasum": ""
},
"require": {
@ -1327,7 +1327,7 @@
"keywords": [
"User management"
],
"time": "2016-02-11 16:30:08"
"time": "2016-03-08 11:05:28"
},
{
"name": "gedmo/doctrine-extensions",
@ -1453,23 +1453,23 @@
},
{
"name": "grandt/phpepub",
"version": "4.0.3",
"version": "v4.0.6",
"source": {
"type": "git",
"url": "https://github.com/Grandt/PHPePub.git",
"reference": "dee0c5549a8d2c6bf6a1ad5b4ee21d245b711fca"
"reference": "05d309052ddeaf38dea89bae72c6016f27b61108"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Grandt/PHPePub/zipball/dee0c5549a8d2c6bf6a1ad5b4ee21d245b711fca",
"reference": "dee0c5549a8d2c6bf6a1ad5b4ee21d245b711fca",
"url": "https://api.github.com/repos/Grandt/PHPePub/zipball/05d309052ddeaf38dea89bae72c6016f27b61108",
"reference": "05d309052ddeaf38dea89bae72c6016f27b61108",
"shasum": ""
},
"require": {
"grandt/phpresizegif": ">=1.0.3",
"grandt/relativepath": ">=1.0.1",
"grandt/phpresizegif": "~1.0.3",
"grandt/relativepath": "~1.0.1",
"php": ">=5.3.0",
"phpzip/phpzip": ">=2.0.7"
"phpzip/phpzip": "~2.0.7"
},
"type": "library",
"autoload": {
@ -1498,7 +1498,7 @@
"e-book",
"epub"
],
"time": "2015-09-15 08:47:09"
"time": "2016-03-08 21:46:00"
},
{
"name": "grandt/phpresizegif",
@ -1889,16 +1889,16 @@
},
{
"name": "hoa/consistency",
"version": "1.16.01.14",
"version": "1.16.03.03",
"source": {
"type": "git",
"url": "https://github.com/hoaproject/Consistency.git",
"reference": "7656b971a8248a8d314ed0c5bb0668936438f62a"
"reference": "aa7e30f99aa2ae476f83800d3ad350506eec153b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/hoaproject/Consistency/zipball/7656b971a8248a8d314ed0c5bb0668936438f62a",
"reference": "7656b971a8248a8d314ed0c5bb0668936438f62a",
"url": "https://api.github.com/repos/hoaproject/Consistency/zipball/aa7e30f99aa2ae476f83800d3ad350506eec153b",
"reference": "aa7e30f99aa2ae476f83800d3ad350506eec153b",
"shasum": ""
},
"require": {
@ -1906,7 +1906,7 @@
"php": ">=5.5.0"
},
"require-dev": {
"hoa/stream": "~0.0",
"hoa/stream": "~1.0",
"hoa/test": "~2.0"
},
"type": "library",
@ -1948,7 +1948,7 @@
"keyword",
"library"
],
"time": "2016-01-14 10:26:48"
"time": "2016-03-03 09:37:24"
},
{
"name": "hoa/event",
@ -2243,16 +2243,16 @@
},
{
"name": "hoa/protocol",
"version": "1.16.01.11",
"version": "1.16.03.07",
"source": {
"type": "git",
"url": "https://github.com/hoaproject/Protocol.git",
"reference": "97a33357e9f0827b75e19a78429d037fab18c1ce"
"reference": "0745015373812591b1fe2e8229b8815d9250d95a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/hoaproject/Protocol/zipball/97a33357e9f0827b75e19a78429d037fab18c1ce",
"reference": "97a33357e9f0827b75e19a78429d037fab18c1ce",
"url": "https://api.github.com/repos/hoaproject/Protocol/zipball/0745015373812591b1fe2e8229b8815d9250d95a",
"reference": "0745015373812591b1fe2e8229b8815d9250d95a",
"shasum": ""
},
"require": {
@ -2299,7 +2299,7 @@
"stream",
"wrapper"
],
"time": "2016-01-11 08:41:20"
"time": "2016-03-07 16:31:08"
},
{
"name": "hoa/regex",
@ -2833,21 +2833,25 @@
},
{
"name": "j0k3r/php-readability",
"version": "v1.0.9",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/j0k3r/php-readability.git",
"reference": "41d7440c6e6130bacd50808342fe566e28f536fb"
"reference": "dec4514c00abf024c570ca496d844e70494b7cda"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/j0k3r/php-readability/zipball/41d7440c6e6130bacd50808342fe566e28f536fb",
"reference": "41d7440c6e6130bacd50808342fe566e28f536fb",
"url": "https://api.github.com/repos/j0k3r/php-readability/zipball/dec4514c00abf024c570ca496d844e70494b7cda",
"reference": "dec4514c00abf024c570ca496d844e70494b7cda",
"shasum": ""
},
"require": {
"monolog/monolog": "^1.13.1",
"php": ">=5.3.3"
},
"require-dev": {
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"autoload": {
"psr-4": {
@ -2891,7 +2895,7 @@
"extraction",
"html"
],
"time": "2015-11-10 08:55:29"
"time": "2016-03-01 14:14:36"
},
{
"name": "j0k3r/safecurl",
@ -3732,16 +3736,16 @@
},
{
"name": "monolog/monolog",
"version": "1.17.2",
"version": "1.18.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24"
"reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/bee7f0dc9c3e0b69a6039697533dca1e845c8c24",
"reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/e19b764b5c855580e8ffa7e615f72c10fd2f99cc",
"reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc",
"shasum": ""
},
"require": {
@ -3770,6 +3774,7 @@
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-mongo": "Allow sending log messages to a MongoDB server",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
"php-console/php-console": "Allow sending log messages to Google Chrome",
"raven/raven": "Allow sending log messages to a Sentry server",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
@ -3779,7 +3784,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.16.x-dev"
"dev-master": "2.0.x-dev"
}
},
"autoload": {
@ -3805,7 +3810,7 @@
"logging",
"psr-3"
],
"time": "2015-10-14 12:51:02"
"time": "2016-03-01 18:00:40"
},
{
"name": "neitanod/forceutf8",
@ -4114,16 +4119,16 @@
},
{
"name": "paragonie/random_compat",
"version": "v1.2.1",
"version": "v1.2.2",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "f078eba3bcf140fd69b5fcc3ea5ac809abf729dc"
"reference": "b3313b618f4edd76523572531d5d7e22fe747430"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/f078eba3bcf140fd69b5fcc3ea5ac809abf729dc",
"reference": "f078eba3bcf140fd69b5fcc3ea5ac809abf729dc",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/b3313b618f4edd76523572531d5d7e22fe747430",
"reference": "b3313b618f4edd76523572531d5d7e22fe747430",
"shasum": ""
},
"require": {
@ -4158,7 +4163,7 @@
"pseudorandom",
"random"
],
"time": "2016-02-29 17:25:04"
"time": "2016-03-11 19:54:08"
},
{
"name": "phpcollection/phpcollection",
@ -4508,16 +4513,16 @@
},
{
"name": "sensio/framework-extra-bundle",
"version": "v3.0.13",
"version": "v3.0.14",
"source": {
"type": "git",
"url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git",
"reference": "bf6be511f4f66d368baeb2cab617203d73cccf4e"
"reference": "cccf975c565ccd835bddc30a8fea5cdfe3357bf1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/bf6be511f4f66d368baeb2cab617203d73cccf4e",
"reference": "bf6be511f4f66d368baeb2cab617203d73cccf4e",
"url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/cccf975c565ccd835bddc30a8fea5cdfe3357bf1",
"reference": "cccf975c565ccd835bddc30a8fea5cdfe3357bf1",
"shasum": ""
},
"require": {
@ -4566,7 +4571,7 @@
"annotations",
"controllers"
],
"time": "2016-02-12 08:17:23"
"time": "2016-03-01 10:50:07"
},
{
"name": "sensiolabs/security-checker",
@ -4945,20 +4950,20 @@
},
{
"name": "symfony/monolog-bundle",
"version": "v2.8.2",
"version": "v2.9.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/monolog-bundle.git",
"reference": "84785c4d44801c4dd82829fa2e1820cacfe2c46f"
"reference": "27c2e3eaec7a0ba3462f99ea92678cbfc7b146e4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/84785c4d44801c4dd82829fa2e1820cacfe2c46f",
"reference": "84785c4d44801c4dd82829fa2e1820cacfe2c46f",
"url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/27c2e3eaec7a0ba3462f99ea92678cbfc7b146e4",
"reference": "27c2e3eaec7a0ba3462f99ea92678cbfc7b146e4",
"shasum": ""
},
"require": {
"monolog/monolog": "~1.8",
"monolog/monolog": "~1.12",
"php": ">=5.3.2",
"symfony/config": "~2.3|~3.0",
"symfony/dependency-injection": "~2.3|~3.0",
@ -4972,7 +4977,7 @@
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "2.8.x-dev"
"dev-master": "2.9.x-dev"
}
},
"autoload": {
@ -5000,26 +5005,29 @@
"log",
"logging"
],
"time": "2015-11-17 10:02:29"
"time": "2016-03-01 17:53:42"
},
{
"name": "symfony/polyfill-intl-icu",
"version": "v1.1.0",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-icu.git",
"reference": "66b0bb4abda229bc073eff6bbc8f2685bdaac165"
"reference": "8328069d9f5322f0e7b3c3518485acfdc94c3942"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/66b0bb4abda229bc073eff6bbc8f2685bdaac165",
"reference": "66b0bb4abda229bc073eff6bbc8f2685bdaac165",
"url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/8328069d9f5322f0e7b3c3518485acfdc94c3942",
"reference": "8328069d9f5322f0e7b3c3518485acfdc94c3942",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/intl": "~2.3|~3.0"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
@ -5055,11 +5063,11 @@
"portable",
"shim"
],
"time": "2016-01-20 09:13:37"
"time": "2016-02-26 16:18:12"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.1.0",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
@ -5118,7 +5126,7 @@
},
{
"name": "symfony/polyfill-php56",
"version": "v1.1.0",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php56.git",
@ -5174,16 +5182,16 @@
},
{
"name": "symfony/polyfill-php70",
"version": "v1.1.0",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php70.git",
"reference": "8428ceddbbaf102f2906769a8ef2438220c5cb95"
"reference": "386c1be9cad3ab531425211919e78c37971be4ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/8428ceddbbaf102f2906769a8ef2438220c5cb95",
"reference": "8428ceddbbaf102f2906769a8ef2438220c5cb95",
"url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/386c1be9cad3ab531425211919e78c37971be4ce",
"reference": "386c1be9cad3ab531425211919e78c37971be4ce",
"shasum": ""
},
"require": {
@ -5229,11 +5237,11 @@
"portable",
"shim"
],
"time": "2016-01-25 08:44:42"
"time": "2016-01-28 22:42:02"
},
{
"name": "symfony/polyfill-util",
"version": "v1.1.0",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-util.git",
@ -5757,17 +5765,17 @@
},
{
"name": "willdurand/hateoas-bundle",
"version": "1.1.0",
"version": "1.1.1",
"target-dir": "Bazinga/Bundle/HateoasBundle",
"source": {
"type": "git",
"url": "https://github.com/willdurand/BazingaHateoasBundle.git",
"reference": "205a5a16899716f33edfb7a5afc4d451d0d2d0b2"
"reference": "a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/willdurand/BazingaHateoasBundle/zipball/205a5a16899716f33edfb7a5afc4d451d0d2d0b2",
"reference": "205a5a16899716f33edfb7a5afc4d451d0d2d0b2",
"url": "https://api.github.com/repos/willdurand/BazingaHateoasBundle/zipball/a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5",
"reference": "a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5",
"shasum": ""
},
"require": {
@ -5776,6 +5784,7 @@
"willdurand/hateoas": "~2.9"
},
"require-dev": {
"phpunit/phpunit": "~4.5",
"symfony/expression-language": "~2.4 || ~3.0",
"twig/twig": "~1.12"
},
@ -5805,7 +5814,7 @@
"HATEOAS",
"rest"
],
"time": "2015-12-07 08:25:05"
"time": "2016-02-22 13:12:41"
},
{
"name": "willdurand/jsonp-callback-validator",

View File

@ -1,42 +1,48 @@
nginx:
image: nginx
ports:
- "8080:80"
volumes:
- ./docker/nginx/nginx.conf:/nginx.conf
- ./docker/logs/nginx:/var/log/nginx
- .:/var/www/html
links:
- php:php
command: nginx -c /nginx.conf
php:
build: docker/php
ports:
- "9000:9000"
volumes:
- .:/var/www/html
#links:
# - "postgres:rdbms"
# - "mariadb:rdbms"
env_file:
- ./docker/php/env
# Comment non-used DBMS lines
# If all DBMS are commented out, sqlite will be used as default
# - ./docker/postgres/env
# - ./docker/mariadb/env
#postgres:
# image: postgres:9
# ports:
# - "5432:5432"
# volumes:
# - ./docker/data/pgsql:/var/lib/postgresql/data
# env_file:
# - ./docker/postgres/env
#mariadb:
# image: mariadb:10
# ports:
# - "3306:3306"
# volumes:
# - ./docker/data/mariadb:/var/lib/mysql
# env_file:
# - ./docker/mariadb/env
version: '2'
services:
nginx:
image: nginx
ports:
- "8080:80"
volumes:
- ./docker/nginx/nginx.conf:/nginx.conf
- ./docker/logs/nginx:/var/log/nginx
- .:/var/www/html
links:
- php:php
command: nginx -c /nginx.conf
php:
build:
context: docker/php
args:
# Set here your timezone using one of this: http://php.net/manual/en/timezones.php
timezone: 'Europe/Monaco'
ports:
- "9000:9000"
volumes:
- .:/var/www/html
#links:
# - "postgres:rdbms"
# - "mariadb:rdbms"
env_file:
- ./docker/php/env
# Comment non-used DBMS lines
# If all DBMS are commented out, sqlite will be used as default
# - ./docker/postgres/env
# - ./docker/mariadb/env
#postgres:
# image: postgres:9
# ports:
# - "5432:5432"
# volumes:
# - ./docker/data/pgsql:/var/lib/postgresql/data
# env_file:
# - ./docker/postgres/env
#mariadb:
# image: mariadb:10
# ports:
# - "3306:3306"
# volumes:
# - ./docker/data/mariadb:/var/lib/mysql
# env_file:
# - ./docker/mariadb/env

View File

@ -1,10 +1,15 @@
FROM php:fpm
# Default timezone. To change it, use the argument in the docker-compose.yml file
ARG timezone='Europe/Paris'
RUN apt-get update && apt-get install -y \
libmcrypt-dev libicu-dev libpq-dev libxml2-dev \
&& docker-php-ext-install \
iconv mcrypt mbstring intl pdo pdo_mysql pdo_pgsql
RUN echo "date.timezone="$timezone > /usr/local/etc/php/conf.d/date_timezone.ini
RUN usermod -u 1000 www-data
CMD ["php-fpm"]

View File

@ -44,3 +44,4 @@ The main documentation for this application is organized into a couple sections:
developer/docker
developer/translate
developer/maintenance
developer/releasing

View File

@ -1,2 +1,49 @@
Filters
=======
=======
To retrieve articles easier, you can use filters.
Click on the third icon in the top bar.
.. image:: ../../img/user/topbar.png
:alt: Top bar
:align: center
All these filters can be combined.
.. image:: ../../img/user/filters.png
:alt: Combine all filters
:align: center
Status
------
Use these checkboxes to find archived or starred articles.
Preview picture
---------------
Check this filter if you want to retrieve articles with a preview picture.
Language
--------
wallabag (via graby) can detect article language. It's easy to you to retrieve articles
written in a specific language.
Reading time
------------
wallabag estimates how many time you need to read an article. With this filter,
you can for example find the articles with a reading time between 2 and 5 minutes.
Domain name
-----------
Thanks to this filter, you can retrieve the articles from the same domain name.
For example, in this field, type ``bbc.co.uk`` to retrieve the articles of this website.
Creation date
-------------
When you save an article, wallabag stored the current date. So handful to retrieve articles written
between 1st and 31th January for example.

View File

@ -4,14 +4,14 @@ Install wallabag
Requirements
------------
wallabag is compatible with php >= 5.5
wallabag is compatible with php >= 5.5, including php 7.
You'll need the following extensions for wallabag to work. Some of these may already activated in your version of php, so you may not have to install all corresponding packages.
- php-session
- php-ctype
- php-dom
- pĥp-hash
- php-hash
- php-simplexml
- php-json
- php-gd
@ -48,7 +48,10 @@ To install wallabag itself, you must run these two commands:
::
SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.0-beta.1" --no-dev
git clone https://github.com/wallabag/wallabag.git
cd wallabag
git checkout 2.0.0-beta.2
SYMFONY_ENV=prod composer install --no-dev -o --prefer-dist
php bin/console wallabag:install --env=prod
To start php's build-in server and test if everything did install correctly, you can do:

View File

@ -1,9 +1,9 @@
Configuration
=============
Maintenant que vous êtes connecté, il est temps de confirurer votre compte.
Maintenant que vous êtes connecté, il est temps de configurer votre compte.
Cliquez sur le menu ``Configuration``. Vous avez accès à 5 onglets:
Cliquez sur le menu ``Configuration``. Vous avez accès à 5 onglets :
``Paramètres``, ``RSS``, ``Mon compte``, ``Mot de passe`` and ``Règles de tag automatiques``.
Paramètres
@ -14,7 +14,7 @@ Thème
L'affichage de wallabag est personnalisable. C'est ici que vous choisissez le thème
que vous préférez. Vous pouvez aussi en créer un nouveau, une documentation sera
disponible pour apprendre comment. Le thème par défaut ``Material``, c'est ce thème
disponible pour guider. Le thème par défaut est ``Material``, c'est celui
qui est utilisé dans les captures d'écran de la documentation.
Nombre d'articles par page
@ -31,12 +31,12 @@ pour que la nouvelle langue soit prise en compte.
RSS
---
wallabag propose un flux RSS for chaque statut d'article : non lus, favoris and lus.
wallabag propose un flux RSS pour chaque statut d'article : non lus, favoris et lus.
Tout d'abord, vous devez vous créer un jeton personnel : cliquez sur ``Créez votre jeton``.
C'est possible de regénérer votre jeton en cliquant sur ``Réinitialisez votre jeton``.
Tout d'abord, vous devez vous créer un jeton personnel : cliquez sur ``Créez votre jeton``.
Il est possible de regénérer votre jeton en cliquant sur ``Réinitialisez votre jeton``.
Vous avez maintenant trois liens, un par statut : ajoutez les dans votre agrégateur de flux RSS préféré.
Vous avez maintenant trois liens, un par statut : ajoutez-les dans votre agrégateur de flux RSS préféré.
Vous pouvez aussi définir combien d'articles vous souhaitez dans vos flux RSS
(50 est la valeur par défaut).
@ -49,16 +49,16 @@ Vous pouvez ici modifier votre nom, votre adresse email et activer la ``Double a
Double authentification (2FA)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Two-factor authentication (also known as 2FA) is a technology patented in
1984 that provides identification of users by means of the combination of two different components.
L'authentification à deux facteurs (également appelée 2FA) est une technologie brevetée en 1984
qui fournit l'identification des utilisateurs au moyen de la combinaison de deux composants différents .
https://en.wikipedia.org/wiki/Two-factor_authentication
https://fr.wikipedia.org/wiki/Authentification_forte
Si vous activer 2FA, à chaque tentative de connexion à wallabag, vous recevrez
Si vous activez 2FA, à chaque tentative de connexion à wallabag, vous recevrez
un code par email. Vous devez renseigner ce code dans le formulaire suivant :
.. image:: ../../img/user/2FA_form.png
:alt: Two factor authentication
:alt: Authentification à deux facteurs
:align: center
Si vous ne souhaitez pas recevoir un code à chaque fois que vous vous connectez,
@ -89,15 +89,15 @@ Comment les utiliser ?
Admettons que vous voulez ajouter comme tag *« lecture rapide »* quand le temps de lecture
d'un article est inférieur à 3 minutes.
Dans ce cas, vous devez ajouter « readingTime <= 3 » dans le champ **Règle** et lecture rapide »* dans le champ **Tags**.
Plusieurs tags peuvent être ajoutés en même temps en les séparant par une virgule : lecture rapide, à lire »*.
Dans ce cas, vous devez ajouter « readingTime <= 3 » dans le champ **Règle** et  lecture rapide »* dans le champ **Tags**.
Plusieurs tags peuvent être ajoutés en même temps en les séparant par une virgule :  lecture rapide, à lire »*.
Des règles complexes peuvent être écrites en utilisant les opérateurs pré-définis :
if *« readingTime >= 5 AND domainName = "github.com" »* then tag as *« long reading, github »*.
Quels variables et opérateurs puis-je utiliser pour écrire mes règles ?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Les variables et opérateurs suivants peuvent être utilisés lors de la création de vos règles :
Les variables et opérateurs suivants peuvent être utilisés lors de la création de vos règles :
=========== ============================================== ========== ==========
Variable Sens Opérateur Sens
@ -110,5 +110,5 @@ content Le contenu de l'article = Égal
language La langue de l'article != Différent de …
mimetype The type MIME de l'article OR Telle règle ou telle autre règle
readingTime Le temps de lecture de l'article, en minutes AND Telle règle et telle règle
domainName Le nom de domaine de l'article matches Contient telle chaine de caractère (insensible à la casse). Exemple : title matches "football"
domainName Le nom de domaine de l'article matches Contient telle chaîne de caractère (insensible à la casse). Exemple : title matches "football"
=========== ============================================== ========== ==========

View File

@ -4,14 +4,14 @@ Se créer un compte
Sur la page de connexion, cliquez sur le bouton ``Créer un compte``.
.. image:: ../../img/user/registration_form.png
:alt: Registration form
:alt: Formulaire de création de compte
:align: center
Vous devez renseigner le formulaire. Faites attention de bien renseigner une adresse
email valide, nous allons vous envoyer un email d'activation.
.. image:: ../../img/user/sent_email.png
:alt: Email was sent to activate account
:alt: Un email a été envoyé pour activer votre compte
:align: center
Vérifiez votre boite de réception, vous avez un nouvel email avec un lien comme celui-ci
@ -21,7 +21,7 @@ Cliquez dessus pour activer votre compte.
Votre compte est maintenant actif.
.. image:: ../../img/user/activated_account.png
:alt: Welcome on board!
:alt: Bienvenue à bord !
:align: center
Foire aux questions

View File

@ -6,12 +6,12 @@ Vous pouvez télécharger chaque article dans plusieurs formats : ePUB, MOBI, PD
Lorsque vous lisez un article, cliquez sur cette icône dans la barre latérale :
.. image:: ../../img/user/download_article.png
:alt: download article
:alt: Télécharger l'article
:align: center
Vous pouvez aussi télécharger une catégorie (non lus, favoris, lus) dans ces formats.
Par exemple, dans la vue **Non lus**, cliquez sur cette icône dans la barre supérieure :
.. image:: ../../img/user/download_articles.png
:alt: download articles
:alt: Télécharger l'article
:align: center

View File

@ -23,5 +23,5 @@ Si wallabag échoue en récupérant l'article, vous pouvez cliquer sur le bouton
(le troisième sur l'image ci-dessous).
.. image:: ../../img/user/refetch.png
:alt: Refetch content
:alt: Réessayer de récupérer le contenu
:align: center

View File

@ -1,2 +1,50 @@
Filtres
=======
Pour retrouver plus facilement vos articles, vous pouvez utiliser les filtres.
Cliquez sur la troisième icône de la barre supérieure.
.. image:: ../../img/user/topbar.png
:alt: Barre supérieure
:align: center
Tous ces filtres peuvent être combinés.
.. image:: ../../img/user/filters.png
:alt: Combine all filters
:align: center
Statut
------
Utilisez ces cases à cocher pour retrouver les articles lus ou mis en favori.
Image de prévisualisation
-------------------------
Cochez ce filtre si vous voulez retrouver les articles avec une image de prévisualisation.
Langage
-------
wallabag (via graby) peut détecter la langue dans laquelle l'article est écrit.
C'est ainsi facile pour vous de retrouver des articles écrits dans une langue spécifique.
Temps de lecture
----------------
wallabag estime combien de temps vous avez besoin pour lire un article.
Avec ce filtre, vous pouvez par exemple retrouver les articles qui ont une estimation
entre 2 et 5 minutes.
Nom de domaine
--------------
Grâce à ce filtre, vous pouvez retrouver les articles venant d'un même nom de domaine.
Par exemple, dans ce champ, saisissez ``lemonde.fr`` pour retrouver les articles de ce site.
Date de création
----------------
Quand vous ajoutez un article, wallabag stocke la date courante.
C'est très pratique pour retrouver les articles ajoutés entre le 1er et le 31 janvier par exemple.

View File

@ -25,7 +25,7 @@ Dans la barre haut de wallabag, vous avez trois icônes. Avec la première icôn
un signe plus, vous pouvez facilement ajouter un nouvel article.
.. image:: ../../img/user/topbar.png
:alt: Top bar
:alt: Barre supérieure
:align: center
Cliquez dessus pour afficher un nouveau champ, collez-y l'URL de l'article et appuyez

View File

@ -10,7 +10,7 @@ Exportez vos données de wallabag 1.x
Sur la page de configuration, cliquez sur ``Export JSON`` dans la section ``Exportez vos données wallabag``.
.. image:: ../../img/user/export_wllbg_1.png
:alt: Export from wallabag 1.x
:alt: Export depuis wallabag 1.x
:align: center
Vous obtiendrez un fichier ``wallabag-export-1-1970-01-01.json``.
@ -21,7 +21,7 @@ Exportez vos données de wallabag 2.x
Dans la barre latérale de téléchargement, cliquez sur ``JSON``.
.. image:: ../../img/user/export_wllbg_2.png
:alt: Export from wallabag 2.x
:alt: Export depuis wallabag 2.x
:align: center
Vous obtiendrez un fichier ``Unread articles.json``.
@ -33,7 +33,7 @@ Cliquez sur le lien ``Importer`` dans le menu, choisissez la version de wallabag
sélectionnez votre fichier d'export sur votre ordinateur et importez-le.
.. image:: ../../img/user/import_wllbg.png
:alt: Import from wallabag 1.x
:alt: Import depuis wallabag 1.x
:align: center
Tous vos articles wallabag seront importés.

View File

@ -4,7 +4,7 @@ Installer wallabag
Pré-requis
------------
wallabag est compatible avec php >= 5.5
wallabag est compatible avec php >= 5.5, php 7 inclus.
Vous aurez besoin des extensions suivantes pour que wallabag fonctionne. Il est possible que certaines de ces extensions soient déjà activées dans votre version de php, donc vous n'avez pas forcément besoin d'installer tous les paquets correspondants.
@ -46,7 +46,10 @@ Pour installer wallabag, vous devez exécuter ces deux commandes :
::
SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.0-beta.1" --no-dev
git clone https://github.com/wallabag/wallabag.git
cd wallabag
git checkout 2.0.0-beta.2
SYMFONY_ENV=prod composer install --no-dev -o --prefer-dist
php bin/console wallabag:install --env=prod
Pour démarrer le serveur interne à php et vérifier que tout s'est installé correctement, vous pouvez exécuter :

View File

@ -9,7 +9,7 @@ Si vous êtes sur un ordinateur de confiance et que vous souhaitez rester connec
vous pouvez cocher la case ``Restez connecté`` : wallabag se souviendra de vous pour un an.
.. image:: ../../img/user/login_form.png
:alt: Login form
:alt: Formulaire de connexion
:align: center
Foire aux questions

BIN
docs/img/user/filters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -88,4 +88,22 @@ class AnnotationRepository extends EntityRepository
->getQuery()
->getOneOrNullResult();
}
/**
* Used only in test case to get the right annotation associated to the right user.
*
* @param string $username
*
* @return Annotation
*/
public function findOneByUsername($username)
{
return $this->createQueryBuilder('a')
->leftJoin('a.user', 'u')
->where('u.username = :username')->setParameter('username', $username)
->orderBy('a.id', 'DESC')
->setMaxResults(1)
->getQuery()
->getSingleResult();
}
}

View File

@ -11,11 +11,12 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase
$annotation = $this->client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagAnnotationBundle:Annotation')
->findOneBy(array('user' => 1));
->findOneByUsername('admin');
if (!$annotation) {
$this->markTestSkipped('No content found in db.');
}
$this->logInAs('admin');
$crawler = $this->client->request('GET', 'annotations/'.$annotation->getEntry()->getId().'.json');
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
@ -32,18 +33,25 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase
$entry = $this->client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findOneBy(array('user' => 1));
->findOneByUsernameAndNotArchived('admin');
$headers = array('CONTENT_TYPE' => 'application/json');
$content = json_encode(array(
'text' => 'my annotation',
'quote' => 'my quote',
'range' => '[{"start":"","startOffset":24,"end":"","endOffset":31}]',
));
'ranges' => array('start' => '', 'startOffset' => 24, 'end' => '', 'endOffset' => 31),
));
$crawler = $this->client->request('POST', 'annotations/'.$entry->getId().'.json', array(), array(), $headers, $content);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertEquals('Big boss', $content['user']);
$this->assertEquals('v1.0', $content['annotator_schema_version']);
$this->assertEquals('my annotation', $content['text']);
$this->assertEquals('my quote', $content['quote']);
$annotation = $this->client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagAnnotationBundle:Annotation')
@ -57,25 +65,56 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase
$annotation = $this->client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagAnnotationBundle:Annotation')
->findOneBy(array('user' => 1));
->findOneByUsername('admin');
$this->logInAs('admin');
$headers = array('CONTENT_TYPE' => 'application/json');
$content = json_encode(array(
'text' => 'a modified annotation',
));
));
$crawler = $this->client->request('PUT', 'annotations/'.$annotation->getId().'.json', array(), array(), $headers, $content);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertEquals('Big boss', $content['user']);
$this->assertEquals('v1.0', $content['annotator_schema_version']);
$this->assertEquals('a modified annotation', $content['text']);
$this->assertEquals('my quote', $content['quote']);
$annotationUpdated = $this->client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagAnnotationBundle:Annotation')
->findOneById($annotation->getId());
$this->assertEquals('a modified annotation', $annotationUpdated->getText());
}
public function testDeleteAnnotation()
{
$annotation = $this->client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagAnnotationBundle:Annotation')
->findOneByUsername('admin');
$this->logInAs('admin');
$headers = array('CONTENT_TYPE' => 'application/json');
$content = json_encode(array(
'text' => 'a modified annotation',
));
$crawler = $this->client->request('DELETE', 'annotations/'.$annotation->getId().'.json', array(), array(), $headers, $content);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertEquals('a modified annotation', $content['text']);
$annotationUpdated = $this->client->getContainer()
$annotationDeleted = $this->client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagAnnotationBundle:Annotation')
->findAnnotationById($annotation->getId());
$this->assertEquals('a modified annotation', $annotationUpdated->getText());
->findOneById($annotation->getId());
$this->assertNull($annotationDeleted);
}
}

View File

@ -97,6 +97,8 @@ class WallabagRestController extends FOSRestController
* {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
* {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
* {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
* {"name"="starred", "dataType"="boolean", "required"=false, "format"="true or false", "description"="entry already starred"},
* {"name"="archive", "dataType"="boolean", "required"=false, "format"="true or false", "description"="entry already archived"},
* }
* )
*
@ -107,6 +109,8 @@ class WallabagRestController extends FOSRestController
$this->validateAuthentication();
$url = $request->request->get('url');
$isArchived = $request->request->get('archive');
$isStarred = $request->request->get('starred');
$entry = $this->get('wallabag_core.content_proxy')->updateEntry(
new Entry($this->getUser()),
@ -118,8 +122,17 @@ class WallabagRestController extends FOSRestController
$this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
}
if (true === (bool) $isStarred) {
$entry->setStarred(true);
}
if (true === (bool) $isArchived) {
$entry->setArchived(true);
}
$em = $this->getDoctrine()->getManager();
$em->persist($entry);
$em->flush();
$json = $this->get('serializer')->serialize($entry, 'json');
@ -327,6 +340,21 @@ class WallabagRestController extends FOSRestController
return $this->renderJsonResponse($json);
}
/**
* Retrieve version number.
*
* @ApiDoc()
*
* @return Response
*/
public function getVersionAction()
{
$version = $this->container->getParameter('wallabag_core.version');
$json = $this->get('serializer')->serialize($version, 'json');
return $this->renderJsonResponse($json);
}
/**
* Validate that the first id is equal to the second one.

View File

@ -162,6 +162,24 @@ class WallabagRestControllerTest extends WallabagApiTestCase
$this->assertCount(1, $content['tags']);
}
public function testPostArchivedAndStarredEntry()
{
$this->client->request('POST', '/api/entries.json', array(
'url' => 'http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html',
'archive' => true,
'starred' => true,
));
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThan(0, $content['id']);
$this->assertEquals('http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', $content['url']);
$this->assertEquals(true, $content['is_archived']);
$this->assertEquals(true, $content['is_starred']);
}
public function testPatchEntry()
{
$entry = $this->client->getContainer()
@ -318,4 +336,15 @@ class WallabagRestControllerTest extends WallabagApiTestCase
$this->assertCount(0, $entries);
}
public function testGetVersion()
{
$this->client->request('GET', '/api/version');
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertEquals($this->client->getContainer()->getParameter('wallabag_core.version'), $content);
}
}

View File

@ -16,7 +16,6 @@ use Wallabag\CoreBundle\Form\Type\RssType;
use Wallabag\CoreBundle\Form\Type\TaggingRuleType;
use Wallabag\CoreBundle\Form\Type\UserInformationType;
use Wallabag\CoreBundle\Tools\Utils;
use Wallabag\UserBundle\Entity\User;
class ConfigController extends Controller
{

View File

@ -0,0 +1,100 @@
<?php
namespace Wallabag\CoreBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Wallabag\ApiBundle\Entity\Client;
use Wallabag\CoreBundle\Form\Type\ClientType;
class DeveloperController extends Controller
{
/**
* List all clients and link to create a new one.
*
* @Route("/developer", name="developer")
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function indexAction()
{
$clients = $this->getDoctrine()->getRepository('WallabagApiBundle:Client')->findAll();
return $this->render('WallabagCoreBundle:Developer:index.html.twig', array(
'clients' => $clients,
));
}
/**
* Create a client (an app).
*
* @param Request $request
*
* @Route("/developer/client/create", name="developer_create_client")
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function createClientAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$client = new Client();
$clientForm = $this->createForm(ClientType::class, $client);
$clientForm->handleRequest($request);
if ($clientForm->isValid()) {
$client->setAllowedGrantTypes(array('token', 'authorization_code', 'password'));
$em->persist($client);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'New client created.'
);
return $this->render('WallabagCoreBundle:Developer:client_parameters.html.twig', array(
'client_id' => $client->getPublicId(),
'client_secret' => $client->getSecret(),
));
}
return $this->render('WallabagCoreBundle:Developer:client.html.twig', array(
'form' => $clientForm->createView(),
));
}
/**
* Remove a client.
*
* @param Client $client
*
* @Route("/developer/client/delete/{id}", requirements={"id" = "\d+"}, name="developer_delete_client")
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function deleteClientAction(Client $client)
{
$em = $this->getDoctrine()->getManager();
$em->remove($client);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'Client deleted'
);
return $this->redirect($this->generateUrl('developer'));
}
/**
* Display developer how to use an existing app.
*
* @Route("/developer/howto/first-app", name="developer_howto_firstapp")
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function howtoFirstAppAction()
{
return $this->render('WallabagCoreBundle:Developer:howto_app.html.twig');
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Wallabag\CoreBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ClientType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('redirect_uris', UrlType::class, array('required' => true, 'label' => 'Redirect URIs'))
->add('save', SubmitType::class, array('label' => 'Create a new client'))
;
$builder->get('redirect_uris')
->addModelTransformer(new CallbackTransformer(
function ($originalUri) {
return $originalUri;
},
function ($submittedUri) {
return array($submittedUri);
}
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Wallabag\ApiBundle\Entity\Client',
));
}
public function getBlockPrefix()
{
return 'client';
}
}

View File

@ -0,0 +1,242 @@
#Login
Keep me logged in: 'Mantenme conectado'
Forgot your password?: '¿Ha olvidado su contraseña?'
Login: 'Conectarse'
Back to login: 'Revenir au formulaire de connexion'
Send: 'Envíar'
"Enter your email address below and we'll send you password reset instructions.": "Introduce tu dirección de email y le enviaremos las instrucciones para resetear la contraseña"
Register: 'Registrarse'
# Menu
unread: 'Sin leer'
starred: 'Favoritos'
archive: 'Archivo'
all: 'Todos los artículos'
tags: 'Tags'
config: 'Configuración'
internal settings: 'Configuración interna'
import: 'Importar'
howto: 'Ayuda'
logout: 'Desconectarse'
Filtered: 'Articulos filtrados'
About: 'Acerca de'
# Header
Back to unread articles: 'Volver a los artículos sin leer'
Add a new entry: 'Añadir un nuevo artículo'
Search: 'Buscar'
Filter entries: 'Filtrar los artículos'
Enter your search here: 'Introduce tu búsqueda aquí'
Save new entry: 'Guardar un nuevo artículo'
Export: 'Exportar'
# Config screen
Settings: 'Configuración'
User information: 'Información de usuario'
Password: 'Contraseña'
RSS: 'RSS'
Add a user: 'Añadir un usuario'
Theme: 'Tema'
Items per page: "Número de artículos por página"
Language: 'Idioma'
Save: 'Enregistrer'
RSS token: 'RSS token'
RSS token updated: 'RSS token actualizado '
Name: 'Nombre'
Email: 'Direccion e-mail'
No token: 'Aucun jeton généré'
Reset your token: 'Resetear token'
Create your token: 'Crear token'
Rss limit: "Límite de artículos en feed RSS"
RSS links: 'URL de su feed RSS'
"RSS feeds provided by wallabag allow you to read your saved articles with your favourite RSS reader. You need to generate a token first.": "Los feeds RSS de wallabag permiten leer los artículos guardados con su lector RSS favorito. Necesita generar un token primero"
Old password: 'Contraseña actual'
New password: 'Nueva contraseña'
Repeat new password: 'Confirmar la nueva contraseña'
Username: "Nombre de usuario"
Two factor authentication: "Autentificación de dos factores"
"Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion": "Con la autentificación de dos factores recibirá código mediante email en cada nueva conexión que no sea de confianza"
# Tagging rules
Tagging rules: "Reglas de etiquetado automáticas"
What does « tagging rules » mean?: "¿Qué significa reglas de etiquetado autómaticas?"
"They are rules used by Wallabag to automatically tag new entries.<br />Each time a new entry is added, all the tagging rules will be used to add the tags you configured, thus saving you the trouble to manually classify your entries.": "Son las reglas usadas por Wallabag para etiquetar automáticamente los nuevos artículos.<br />Cáda vez que un nuevo artículo es añadido, todas las reglas de etiquetado automáticas serán usadas para etiquetarlo, ayudandote a clasificar automáticamente los artículos."
How do I use them?: "¿Cómo se utilizan?"
"Let assume you want to tag new entries as « <i>short reading</i> » when the reading time is inferior to 3 minutes.<br />In that case, you should put « readingTime &lt;= 3 » in the <i>Rule</i> field and « <i>short reading</i> » in the <i>Tags</i> field.<br />Several tags can added simultaneously by separating them by a comma: « <i>short reading, must read</i> »<br />Complex rules can be written by using predefined operators: if « <i>readingTime &gt;= 5 AND domainName = \"github.com\"</i> » then tag as « <i>long reading, github </i> »": "Imaginons que voulez attribuer aux nouveaux articles le tag « <i>lecture courte</i> » lorsque le temps de lecture est inférieur à 3 minutes.<br />Dans ce cas, vous devriez mettre « readingTime &lt;= 3 » dans le champ <i>Règle</i> et « <i>lecture courte</i> » dans le champ <i>Tag</i>.<br />Plusieurs tags peuvent être ajoutés simultanément en les séparant par des virgules : « <i>lecture courte, à lire</i> »<br />Des règles complexes peuvent être créées en utilisant des opérateurs prédéfinis: si « <i>readingTime &gt;= 5 AND domainName = \"github.com\"</i> » alors attribuer les tags « <i>lecteur longue, github </i> »"
Which variables and operators can I use to write rules?: "¿Qué variables y operadores se pueden utilizar para escribir las reglas?"
The following variables and operators can be used to create tagging rules:: "Las siguientes variables y operadores se pueden utilizar para crear las reglas de etiquetado automáticas:"
Variable: "Variable"
Meaning: "Significado"
Operator: "Operador"
Title of the entry: "Titúlo del artículo"
Less than…: "Menos que…"
URL of the entry: "URL del artículo"
Strictly less than…: "Estrictámente menos que…"
Whether the entry is archived or not: "El artículo está guardado o no"
Greater than…: "Más que…"
Whether the entry is starred or not: "Si el artículo es un favorito o no"
Strictly greater than…: "Estrictámente mas que…"
The entry's content: "El contenido del artículo"
Equal to…: "Egual a…"
The entry's language: "El idoma del artículo"
Not equal to…: "Diferente de…"
The entry's mime-type: "Tipo MIME del artículo"
One rule or another: "Una regla o otra"
The estimated entry's reading time, in minutes: "El tiempo estimado de lectura del artículo, en minutos"
One rule and another: "Una regla y la otra"
The domain name of the entry: "El dominio del artículo"
"Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches \"football\"</code>": "Prueba si un <i>sujeto</i> corresponde a una <i>busqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>título coincide \"football\"</code>"
Rule: "Regla"
FAQ: "FAQ"
# Entries
"estimated reading time: %readingTime% min": "tiempo estimado de lectura: %readingTime% min"
"estimated reading time: %inferior% 1 min": "tiempo estimado de lectura: %inferior% 1 min"
original: "original"
Toggle mark as read: 'Marcar cómo leído/ no leído'
Toggle favorite: 'Marcar cómo favorito/ no favorito'
Delete: 'Suprimir'
"{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.": "{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos."
http://website: "http://website"
"{0} No annotations|{1} One annotation|]1,Inf[ %nbAnnotations% annotations": "{0} Sin anotaciones|{1} Una anotación|]1,Inf[ %nbAnnotations% anotaciones"
# Edit entry
Edit an entry: "Editar una artículo"
Title: "Título"
Is public: "Es Público"
# tag
Tags: Tags
"{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.": "{0} No hay ningun tag.|{1} Hay un tag.|]1,Inf[ Hay %count% tags."
# Filters
Filters: 'Filtros'
Status: 'Estatus'
Archived: 'Archivado'
Starred: 'Favorito'
Preview picture: 'Foto de preview'
Has a preview picture: 'Hay una foto'
Reading time in minutes: 'Duración de lectura en minutos'
from: 'de'
to: 'a'
website.com: 'website.com'
Domain name: 'Nombre de dominio'
Creation date: 'Fecha de creación'
dd/mm/yyyy: 'dd/mm/aaaa'
Clear: 'Limpiar'
Filter: 'Filtrar'
website.com: "website.com"
# About
About: "Acerca de"
Who is behind wallabag: "Equipo de desarrollo de wallabag"
Getting help: "Conseguir ayuda"
Helping wallabag: "Ayudar a wallabag"
Developed by: "Desarrollado por"
website: "Sitio web"
And many others contributors ♥: "Y muchos otros contribuidores ♥"
on GitHub: "en GitHub"
Project website: "Web del proyecto"
License: "Licencia"
Version: "Versión"
Documentation: "Documentación"
Bug reports: "Reporte de errores"
On our support website: "En nuestra web de soporte"
or: "o"
"wallabag is free and opensource. You can help us:": "wallabag es libre y gratuito. Usted puede ayudarnos :"
"by contributing to the project:": "contribuyendo al proyecto :"
an issue lists all our needs: "nuestras necesidades están en un ticket"
via Paypal: "via Paypal"
Take wallabag with you: "Llevate wallabag contigo"
Social: "Social"
powered by: "propulsé par"
Contributors: "Contribuidores"
Thank you to contributors on wallabag web application: "Gradias a los contribuidores de la aplicación web de wallabag"
Third-party libraries: "Librerías de terceeros"
"Here are the list of third-party libraries used in wallabag (with their licenses):": "Aquí está la lista de las dependencias utilizadas por wallabag (con sus licencias):"
Package: Paquete
License: Licencia
# Howto
Form: "Formulario"
Thanks to this form: "Gracias a este formulario"
Browser addons: "Extensiones de navigador"
Mobile apps: "Applicaciones para smartphone"
Bookmarklet: "Bookmarklet"
Standard Firefox Add-On: "Extensión Firefox"
Chrome Extension: "Extensión Chrome"
download the application: "descargar la aplicación"
"Drag &amp; drop this link to your bookmarks bar:": "Desplazar y soltar este link en la barra de marcadores :"
# Flash messages
Information updated: "Su información personal ha sido actualizada"
"Config saved. Some parameters will be considered after disconnection.": "Configuración guardada. Algunos parámetros serán recargados cuando se vuelva a conectar."
RSS information updated: "La configuración de los feeds RSS ha sido actualizada"
Password updated: "Contraseña actualizada"
Entry starred: "Artículo guardado en los favoritos"
Entry unstarred: "Artículo retirado de los favoritos"
Entry archived: "Artículo archivado"
Entry unarchived: "Artículo desarchivado"
Entry deleted: "Artículo suprimido"
Tagging rule deleted: "Regla de etiquetado borrada"
Tagging rules updated: "Regla de etiquetado actualizada"
User "%username%" added: 'Usuario "%username%" añadido'
In demonstration mode, you can't change password for this user.: 'En modo demo, no puedes cambiar la contraseña del usuario.'
# Entry
Mark as read: 'Marcar como leído'
Favorite: 'Marcar cómo favorito'
back: 'Volver'
original article: 'Artículo original'
Add a tag: 'Añadir una etiqueta'
Share: 'Compartir'
Download: 'Descargar'
Does this article appear wrong?: "¿Este artículo no se muestra bien?"
Problems?: '¿Algún problema?'
Edit title: "Modificar el título"
Re-fetch content: "Redescargar el contenido"
Tag added: "Etiqueta añadida"
# Import
Welcome to wallabag importer. Please select your previous service that you want to migrate.: "Bienvenido al útil de migración de wallabag. Seleccione el servicio previo del que usted quiera migrar."
"This importer will import all your Pocket data. Pocket doesn't allow us to retrieve content from their service, so the readable content of each article will be re-fetched by wallabag.": "Va a importar sus datos de Pocket. Pocket no nos permite descargar el contenido de su servicio, así que el contenido de cada artículo será redescargado por wallabag."
"This importer will import all your wallabag v1 articles. On your config page, click on \"JSON export\" in the \"Export your wallabag data\" section. You will have a \"wallabag-export-1-xxxx-xx-xx.json\" file.": "Va a importar sus artículos de wallabag v1. En su configuración de wallabag v1, pulse sobre \"Exportar JSON\" dentro de la sección \"Exportar sus datos de wallabag\". Usted tendrá un fichero \"wallabag-export-1-xxxx-xx-xx.json\"."
"This importer will import all your wallabag v2 articles. Go to All articles, then, on the export sidebar, click on \"JSON\". You will have a \"All articles.json\" file.": "Va a importar sus artículos de otra instancia de wallabag v2. Vaya a Todos los artículos, entonces, en la barra lateral, clickee en \"JSON\". Usted tendrá un fichero \"All articles.json\""
"You can import your data from your Pocket account. You just have to click on the below button and authorize the application to connect to getpocket.com.": "Puedes importar sus datos desde su cuenta de Pocket. Sólo tienes que pulsar en el botón para autrizar que wallabag se conecte a getpocket.com."
Import > Pocket: "Importar > Pocket"
Pocket import isn't configured.: "La importación de Pocket no está configurada."
You need to define %keyurls% a pocket_consumer_key %keyurle%.: "Debe definir %keyurls% una clava del API Pocket %keyurle%."
Your server admin needs to define an API Key for Pocket.: "El administrador de vuestro servidor debe definir una clave API Pocket."
Connect to Pocket and import data: "Conectese a Pocket para importar los datos"
Please select your wallabag export and click on the below button to upload and import it.: "Seleccione el fichero de su exportación de wallabag v1 y puelse en el botón para subirla y importarla."
File: "Fichero"
Upload file: "Importar el fichero"
Import contents: "Importar los contenidos"
Import: "Importar"
Import > Wallabag v1: "Importar > Wallabag v1"
Import > Wallabag v2: "Importar > Wallabag v2"
# Quickstart
Quickstart: Comienzo rápido
Welcome to wallabag!: "Bienvenido a wallabag !"
We'll accompany you to visit wallabag and show you some features which can interess you.: "Le acompañaremos a su visita de wallabag y le mostraremos algunas características que le pueden interesar."
Follow us!: "¡Siganos!"
Configure the application: "Configure la aplicación"
Change language and design: "Cambie el idoma y el diseño de la aplicación"
Enable RSS feeds: "Activar los feeds RSS"
First steps: "Prieros pasos"
Save your first article: "Guarde su primer artículo"
And classify it!: "¡Y clasifiquelo!"
Migrate from an existing service: "Migrar de un servicio existente"
You're using an other service? We'll help you to retrieve your data on wallabag.: "¿Está usando otro servicio? Le ayudaremos a migrar sus datos a wallabag."
Migrate from Pocket: "Migrar desde Pocket"
Migrate from wallabag v1: "Migrar desde wallabag v1"
Full documentation: "Documentación completa"
Convert your articles into ePUB or PDF: "Convierta sus artículos a ePub o a PDF"
See how you can look for an article by using search engine and filters: "Aprenda a utilizar el buscador y los filtros para encontrar el artículo que le interese"
And so many other articles!: "¡Y muchos más artículos!"
Support: "Soporte"
If you need some help, we are here for you.: "Sí necesita ayuda, estamos disponibles para usted."
On GitHub: "En GitHub"
By email: "Por email"
On Gitter: "On Gitter"

View File

@ -215,6 +215,8 @@ Import contents: "Importer les contenus"
Import: "Importer"
Import > Wallabag v1: "Importer > Wallabag v1"
Import > Wallabag v2: "Importer > Wallabag v2"
Mark all as read ?: "Marquer tout comme lu ?"
Mark all imported entries as read: "Marquer tous les contenus importés comme lus"
# Quickstart
Quickstart: Pour bien débuter
@ -240,3 +242,36 @@ If you need some help, we are here for you.: "Parce que vous avez peut-être bes
On GitHub: "Sur GitHub"
By email: "Par email"
On Gitter: "Sur Gitter"
# developer
Developer: Développeur
Welcome to the wallabag API: "Bienvenue sur l'API de wallabag"
How to create my first application: "Comment créer votre première application"
View full API documentation: "Voir la documentation complète de l'API"
Clients: "Clients"
Create a new client: "Créer une nouveau client"
Existing clients: "Les clients existants"
Client ID: "ID Client"
Client secret: "Clé secrète"
Redirect URIs: "URLs de redirection"
Grant type allowed: "Type de privilège accordé"
You have the ability to remove this client. This action is IRREVERSIBLE !: "Vous avez la possibilité de supprimer un client. Cette action est IRREVERSIBLE !"
If you remove it, every app configured with that client won't be able to auth on your wallabag.: "Si vous supprimez un client, toutes les applications qui l'utilisaient ne fonctionneront plus avec votre compte wallabag."
Remove this client: "Supprimer ce client"
New client: "Nouveau client"
You are about to create a new client. Please fill the field below for the redirect URI of your application.: "Vous allez créer un nouveau client. Merci de remplir l'url de redirection vers votre application."
Back: "Retour"
Client parameters: "Les paramètres de votre client"
New client created.: "Nouveau client créé."
Here are your client parameters.: "Voilà les paramètres de votre client"
Read the howto "Create my first application": "Lire \"comment créer ma première application\""
Client deleted: "Client supprimé"
No client yet.: "Aucun client pour le moment"
"The following commands make use of the <a href=\"https://github.com/jkbrzt/httpie\">HTTPie library</a>. Make sure it is installed on your system before using it.": "Les commandes suivantes utilisent la <a href=\"https://github.com/jkbrzt/httpie\">librarie HTTPie</a>. Assurez-vous qu'elle soit installée avant de l'utiliser."
You need a token to communicate between your 3rd application and wallabag API.: "Vous avez besoin d'un token pour échanger entre votre application et l'API de wallabag."
"To create this token, you need <a href=\"%link%\">to create a new client</a>.": "Pour créer un token, vous devez <a href=\"%link%\">créer un nouveau client</a>."
Now, create your token (replace client_id, client_secret, username and password with the good values):: "Maintenant créez votre token (remplacer client_id, client_secret, username et password avec les bonnes valeurs):"
The API will return a response like this:: "L'API vous retournera une réponse comme ça:"
The access_token is useful to do a call to the API endpoint. For example:: "L'access_token doit être utilisé pour faire un appel à l'API. Par exemple :"
This call will return all the entries for your user.: "Cet appel va retourner tous les articles de l'utilisateur."
"If you want to see all the API endpoints, you can have a look <a href=\"%link%\">to our API documentation</a>.": "Si vous voulez toutes les méthodes de l'API, jetez un oeil <a href=\"%link%\">à la documentation de l'API</a>."

View File

@ -0,0 +1,3 @@
# Config screen
The password fields must match: 'Las contraseñas no coinciden'
Password should by at least 8 chars long: 'La contraseña debe tener al menos 8 carácteres'

View File

@ -47,7 +47,7 @@
<script src="{{ asset('bundles/wallabagcore/themes/_global/js/annotator.min.js') }}"></script>
{% endblock %}
<title>{% block title %}{% endblock %}</title>
<title>wallabag - {% block title %}{% endblock %}</title>
{% endblock %}
</head>

View File

@ -0,0 +1,31 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}New client{% endtrans %}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<p>{% trans %}You are about to create a new client. Please fill the field below for the redirect URI of your application.{% endtrans %}</p>
{{ form_start(form) }}
{{ form_errors(form) }}
<div class="input-field col s12">
{{ form_label(form.redirect_uris) }}
{{ form_errors(form.redirect_uris) }}
{{ form_widget(form.redirect_uris) }}
</div>
<a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a>
{{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_rest(form) }}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,22 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}Client parameters{% endtrans %}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<p>{% trans %}Here are your client parameters.{% endtrans %}</p>
<ul>
<li>{% trans %}Client ID{% endtrans %}: <strong><pre>{{ client_id }}</pre></strong></li>
<li>{% trans %}Client secret{% endtrans %}: <strong><pre>{{ client_secret }}</pre></strong></li>
</ul>
<a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a>
<a href="{{ path('developer_howto_firstapp') }}" class="btn waves-effect waves-light">{% trans %}Read the howto "Create my first application"{% endtrans %}</a>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,63 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}How to create my first application{% endtrans %}{% endblock %}
{% block css %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-dark.min.css') }}">
{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<p>{% trans %}The following commands make use of the <a href="https://github.com/jkbrzt/httpie">HTTPie library</a>. Make sure it is installed on your system before using it.{% endtrans %}</p>
<p>{% trans %}You need a token to communicate between your 3rd application and wallabag API.{% endtrans %}</p>
<p>{% trans with {'%link%': path('developer_create_client')} %}To create this token, you need <a href="%link%">to create a new client</a>.{% endtrans %}</p>
<p>{% trans %}Now, create your token (replace client_id, client_secret, username and password with the good values):{% endtrans %}</p>
<p>
<pre><code class="language-bash">http POST http://v2.wallabag.org/oauth/v2/token \
grant_type=password \
client_id=12_5um6nz50ceg4088c0840wwc0kgg44g00kk84og044ggkscso0k \
client_secret=3qd12zpeaxes8cwg8c0404g888co4wo8kc4gcw0occww8cgw4k \
username=yourUsername \
password=yourPassw0rd</code></pre>
</p>
<p>{% trans %}The API will return a response like this:{% endtrans %}</p>
<p>
<pre><code class="language-bash">HTTP/1.1 200 OK
Cache-Control: no-store, private
Connection: close
Content-Type: application/json
Date: Tue, 06 Oct 2015 18:24:03 GMT
Host: localhost:8000
Pragma: no-cache
X-Debug-Token: be00a1
X-Debug-Token-Link: /profiler/be00a1
X-Powered-By: PHP/5.5.9-1ubuntu4.13
{
"access_token": "ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw",
"expires_in": 3600,
"refresh_token": "ODBjODU1NWUwNmUzZTBkNDQ5YWVlZTVlMjQ2Y2I0OWM2NTM1ZGM2M2Y3MDhjMTViM2U2MzYxYzRkMDk5ODRlZg",
"scope": null,
"token_type": "bearer"
}</code></pre>
</p>
<p>{% trans %}The access_token is useful to do a call to the API endpoint. For example:{% endtrans %}</p>
<p>
<pre><code class="language-bash">http GET http://v2.wallabag.org/api/entries.json \
"Authorization:Bearer ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw"</code></pre>
</p>
<p>{% trans %}This call will return all the entries for your user.{% endtrans %}</p>
<p>{% trans with {'%link%': path('nelmio_api_doc_index')} %}If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.{% endtrans %}</p>
<p><a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a></p>
</div>
</div>
</div>
</div>
<script src="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/prism.min.js') }}"></script>
<script src="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/components/prism-bash.min.js') }}"></script>
{% endblock %}

View File

@ -0,0 +1,68 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}Developer{% endtrans %}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<h3>{% trans %}Welcome to the wallabag API{% endtrans %}</h3>
<h4>{% trans %}Documentation{% endtrans %}</h4>
<ul>
<li><a href="{{ path('developer_howto_firstapp') }}">{% trans %}How to create my first application{% endtrans %}</a></li>
<li><a href="{{ path('nelmio_api_doc_index') }}">{% trans %}View full API documentation{% endtrans %}</a></li>
</ul>
<h4>{% trans %}Clients{% endtrans %}</h4>
<ul>
<li><a href="{{ path('developer_create_client') }}">{% trans %}Create a new client{% endtrans %}</a></li>
</ul>
<h4>{% trans %}Existing clients{% endtrans %}</h4>
{% if clients %}
<ul class="collapsible" data-collapsible="expandable">
{% for client in clients %}
<li>
<div class="collapsible-header">#{{ client.id }}</div>
<div class="collapsible-body">
<table class="striped">
<tr>
<td>{% trans %}Client ID{% endtrans %}</td>
<td><strong><code>{{ client.id }}_{{ client.randomId }}</code></strong></td>
</tr>
<tr>
<td>{% trans %}Client secret{% endtrans %}</td>
<td><strong><code>{{ client.secret }}</code></strong></td>
</tr>
<tr>
<td>{% trans %}Redirect URIs{% endtrans %}</td>
<td><strong><code>{{ client.redirectUris|json_encode() }}</code></strong></td>
</tr>
<tr>
<td>{% trans %}Grant type allowed{% endtrans %}</td>
<td><strong><code>{{ client.allowedGrantTypes|json_encode() }}</code></strong></td>
</tr>
</table>
<p>
{% trans %}You have the ability to remove this client. This action is IRREVERSIBLE !{% endtrans %}<br/>
{% trans %}If you remove it, every app configured with that client won't be able to auth on your wallabag.{% endtrans %}<br/>
<a class="waves-effect waves-light red btn" href="{{ path('developer_delete_client', {'id': client.id}) }}">{% trans %}Remove this client{% endtrans %}</a>
</p>
</div>
</li>
{% endfor %}
</ul>
{% else %}
{% trans %}No client yet.{% endtrans %}
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -4,32 +4,47 @@
{% block content %}
<h2>{% trans %}Welcome to wallabag!{% endtrans %}</h2>
<h3>{% trans %}Welcome to wallabag!{% endtrans %}</h3>
<p>{% trans %}We'll accompany you to visit wallabag and show you some features which can interess you.{% endtrans %}</p>
<p>{% trans %}Follow us!{% endtrans %}</p>
<h4>{% trans %}Configure the application{% endtrans %}</h4>
<ul>
<li><a href="{{ path('config') }}">{% trans %}Change language and design{% endtrans %}</a></li>
<li><a href="{{ path('config') }}#set2">{% trans %}Enable RSS feeds{% endtrans %}</a></li>
<li><a href="{{ path('config') }}#set5">{% trans %}Write rules to automatically tag your articles{% endtrans %}</a></li>
</ul>
<h3>{% trans %}First steps{% endtrans %}</h3>
{% if is_granted('ROLE_SUPER_ADMIN') %}
<h4>{% trans %}Administration{% endtrans %}</h4>
<p>{% trans %}As a administrator, you have privileges on wallabag. You can:{% endtrans %}</p>
<ul>
<li><a href="{{ path('config') }}#set6">{% trans %}Create a new user{% endtrans %}</a></li>
<li><a href="{{ path('craue_config_settings_modify') }}#set-analytics">{% trans %}Configure analytics{% endtrans %}</a></li>
<li><a href="{{ path('craue_config_settings_modify') }}#set-entry">{% trans %}Enable some parameters about article sharing{% endtrans %}</a></li>
<li><a href="{{ path('craue_config_settings_modify') }}#set-export">{% trans %}Configure export{% endtrans %}</a></li>
<li><a href="{{ path('craue_config_settings_modify') }}#set-import">{% trans %}Configure import{% endtrans %}</a></li>
</ul>
{% endif %}
<h4>{% trans %}First steps{% endtrans %}</h4>
<ul>
<li><a href="{{ path('new') }}">{% trans %}Save your first article{% endtrans %}</a></li>
<li><a href="{{ path('unread') }}">{% trans %}And classify it!{% endtrans %}</a></li>
</ul>
<h3>{% trans %}Migrate from an existing service{% endtrans %}</h3>
<h4>{% trans %}Migrate from an existing service{% endtrans %}</h4>
<p>{% trans %}You're using an other service? We'll help you to retrieve your data on wallabag.{% endtrans %}</p>
<ul>
<li><a href="{{ path('import_pocket') }}">{% trans %}Migrate from Pocket{% endtrans %}</a></li>
<li><a href="{{ path('import_wallabag_v1') }}">{% trans %}Migrate from wallabag v1{% endtrans %}</a></li>
<li><a href="{{ path('import_wallabag_v2') }}">{% trans %}Migrate from wallabag v2{% endtrans %}</a></li>
</ul>
<h3>{% trans %}Full documentation{% endtrans %}</h3>
<h4>{% trans %}Full documentation{% endtrans %}</h4>
<ul>
<li><a href="http://wallabag.readthedocs.org">{% trans %}Convert your articles into ePUB or PDF{% endtrans %}</a></li>
<li><a href="http://wallabag.readthedocs.org">{% trans %}See how you can look for an article by using search engine and filters{% endtrans %}</a></li>
<li><a href="http://wallabag.readthedocs.org">{% trans %}And so many other articles!{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/en/v2/user/annotations.html">{% trans %}Annotate your article{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/en/v2/user/download_articles.html">{% trans %}Convert your articles into ePUB or PDF{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/en/v2/user/filters.html">{% trans %}See how you can look for an article by using search engine and filters{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/en/v2/user/errors_during_fetching.html">{% trans %}What can I do if an article encounters errors during fetching?{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/">{% trans %}And so many other articles!{% endtrans %}</a></li>
</ul>
<h3>{% trans %}Support{% endtrans %}</h3>
<h4>{% trans %}Support{% endtrans %}</h4>
<p>{% trans %}If you need some help, we are here for you.{% endtrans %}</p>
<ul>
<li><a href="https://github.com/wallabag/wallabag/issues/">{% trans %}On GitHub{% endtrans %}</a></li>

View File

@ -56,6 +56,7 @@
{% endif %}
<li><a href="{{ path('import') }}">{% trans %}import{% endtrans %}</a></li>
<li><a href="{{ path('howto') }}">{% trans %}howto{% endtrans %}</a></li>
<li><a href="{{ path('developer') }}">{% trans %}Developer{% endtrans %}</a></li>
<li><a href="{{ path('about') }}">{% trans %}about{% endtrans %}</a></li>
<li><a class="icon icon-power" href="{{ path('fos_user_security_logout') }}" title="{% trans %}logout{% endtrans %}">{% trans %}logout{% endtrans %}</a></li>
</ul>

View File

@ -0,0 +1,31 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}New client{% endtrans %}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<p>{% trans %}You are about to create a new client. Please fill the field below for the redirect URI of your application.{% endtrans %}</p>
{{ form_start(form) }}
{{ form_errors(form) }}
<div class="input-field col s12">
{{ form_label(form.redirect_uris) }}
{{ form_errors(form.redirect_uris) }}
{{ form_widget(form.redirect_uris) }}
</div>
<a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a>
{{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_rest(form) }}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,22 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}Client parameters{% endtrans %}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<p>{% trans %}Here are your client parameters.{% endtrans %}</p>
<ul>
<li>{% trans %}Client ID{% endtrans %}: <strong><pre>{{ client_id }}</pre></strong></li>
<li>{% trans %}Client secret{% endtrans %}: <strong><pre>{{ client_secret }}</pre></strong></li>
</ul>
<a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a>
<a href="{{ path('developer_howto_firstapp') }}" class="btn waves-effect waves-light">{% trans %}Read the howto "Create my first application"{% endtrans %}</a>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,63 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}How to create my first application{% endtrans %}{% endblock %}
{% block css %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-dark.min.css') }}">
{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<p>{% trans %}The following commands make use of the <a href="https://github.com/jkbrzt/httpie">HTTPie library</a>. Make sure it is installed on your system before using it.{% endtrans %}</p>
<p>{% trans %}You need a token to communicate between your 3rd application and wallabag API.{% endtrans %}</p>
<p>{% trans with {'%link%': path('developer_create_client')} %}To create this token, you need <a href="%link%">to create a new client</a>.{% endtrans %}</p>
<p>{% trans %}Now, create your token (replace client_id, client_secret, username and password with the good values):{% endtrans %}</p>
<p>
<pre><code class="language-bash">http POST http://v2.wallabag.org/oauth/v2/token \
grant_type=password \
client_id=12_5um6nz50ceg4088c0840wwc0kgg44g00kk84og044ggkscso0k \
client_secret=3qd12zpeaxes8cwg8c0404g888co4wo8kc4gcw0occww8cgw4k \
username=yourUsername \
password=yourPassw0rd</code></pre>
</p>
<p>{% trans %}The API will return a response like this:{% endtrans %}</p>
<p>
<pre><code class="language-bash">HTTP/1.1 200 OK
Cache-Control: no-store, private
Connection: close
Content-Type: application/json
Date: Tue, 06 Oct 2015 18:24:03 GMT
Host: localhost:8000
Pragma: no-cache
X-Debug-Token: be00a1
X-Debug-Token-Link: /profiler/be00a1
X-Powered-By: PHP/5.5.9-1ubuntu4.13
{
"access_token": "ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw",
"expires_in": 3600,
"refresh_token": "ODBjODU1NWUwNmUzZTBkNDQ5YWVlZTVlMjQ2Y2I0OWM2NTM1ZGM2M2Y3MDhjMTViM2U2MzYxYzRkMDk5ODRlZg",
"scope": null,
"token_type": "bearer"
}</code></pre>
</p>
<p>{% trans %}The access_token is useful to do a call to the API endpoint. For example:{% endtrans %}</p>
<p>
<pre><code class="language-bash">http GET http://v2.wallabag.org/api/entries.json \
"Authorization:Bearer ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw"</code></pre>
</p>
<p>{% trans %}This call will return all the entries for your user.{% endtrans %}</p>
<p>{% trans with {'%link%': path('nelmio_api_doc_index')} %}If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.{% endtrans %}</p>
<p><a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a></p>
</div>
</div>
</div>
</div>
<script src="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/prism.min.js') }}"></script>
<script src="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/components/prism-bash.min.js') }}"></script>
{% endblock %}

View File

@ -0,0 +1,68 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{% trans %}Developer{% endtrans %}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<h3>{% trans %}Welcome to the wallabag API{% endtrans %}</h3>
<h4>{% trans %}Documentation{% endtrans %}</h4>
<ul>
<li><a href="{{ path('developer_howto_firstapp') }}">{% trans %}How to create my first application{% endtrans %}</a></li>
<li><a href="{{ path('nelmio_api_doc_index') }}">{% trans %}View full API documentation{% endtrans %}</a></li>
</ul>
<h4>{% trans %}Clients{% endtrans %}</h4>
<ul>
<li><a href="{{ path('developer_create_client') }}">{% trans %}Create a new client{% endtrans %}</a></li>
</ul>
<h4>{% trans %}Existing clients{% endtrans %}</h4>
{% if clients %}
<ul class="collapsible" data-collapsible="expandable">
{% for client in clients %}
<li>
<div class="collapsible-header">#{{ client.id }}</div>
<div class="collapsible-body">
<table class="striped">
<tr>
<td>{% trans %}Client ID{% endtrans %}</td>
<td><strong><code>{{ client.id }}_{{ client.randomId }}</code></strong></td>
</tr>
<tr>
<td>{% trans %}Client secret{% endtrans %}</td>
<td><strong><code>{{ client.secret }}</code></strong></td>
</tr>
<tr>
<td>{% trans %}Redirect URIs{% endtrans %}</td>
<td><strong><code>{{ client.redirectUris|json_encode() }}</code></strong></td>
</tr>
<tr>
<td>{% trans %}Grant type allowed{% endtrans %}</td>
<td><strong><code>{{ client.allowedGrantTypes|json_encode() }}</code></strong></td>
</tr>
</table>
<p>
{% trans %}You have the ability to remove this client. This action is IRREVERSIBLE !{% endtrans %}<br/>
{% trans %}If you remove it, every app configured with that client won't be able to auth on your wallabag.{% endtrans %}<br/>
<a class="waves-effect waves-light red btn" href="{{ path('developer_delete_client', {'id': client.id}) }}">{% trans %}Remove this client{% endtrans %}</a>
</p>
</div>
</li>
{% endfor %}
</ul>
{% else %}
{% trans %}No client yet.{% endtrans %}
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -16,7 +16,19 @@
<ul>
<li><a href="{{ path('config') }}">{% trans %}Change language and design{% endtrans %}</a></li>
<li><a href="{{ path('config') }}#set2">{% trans %}Enable RSS feeds{% endtrans %}</a></li>
<li><a href="{{ path('config') }}#set5">{% trans %}Write rules to automatically tag your articles{% endtrans %}</a></li>
</ul>
{% if is_granted('ROLE_SUPER_ADMIN') %}
<h4>{% trans %}Administration{% endtrans %}</h4>
<p>{% trans %}As a administrator, you have privileges on wallabag. You can:{% endtrans %}</p>
<ul>
<li><a href="{{ path('config') }}#set6">{% trans %}Create a new user{% endtrans %}</a></li>
<li><a href="{{ path('craue_config_settings_modify') }}#set-analytics">{% trans %}Configure analytics{% endtrans %}</a></li>
<li><a href="{{ path('craue_config_settings_modify') }}#set-entry">{% trans %}Enable some parameters about article sharing{% endtrans %}</a></li>
<li><a href="{{ path('craue_config_settings_modify') }}#set-export">{% trans %}Configure export{% endtrans %}</a></li>
<li><a href="{{ path('craue_config_settings_modify') }}#set-import">{% trans %}Configure import{% endtrans %}</a></li>
</ul>
{% endif %}
<h4>{% trans %}First steps{% endtrans %}</h4>
<ul>
<li><a href="{{ path('new') }}">{% trans %}Save your first article{% endtrans %}</a></li>
@ -27,12 +39,19 @@
<ul>
<li><a href="{{ path('import_pocket') }}">{% trans %}Migrate from Pocket{% endtrans %}</a></li>
<li><a href="{{ path('import_wallabag_v1') }}">{% trans %}Migrate from wallabag v1{% endtrans %}</a></li>
<li><a href="{{ path('import_wallabag_v2') }}">{% trans %}Migrate from wallabag v2{% endtrans %}</a></li>
</ul>
<h4>{% trans %}Developers{% endtrans %}</h4>
<ul>
<li><a href="{{ path('developer') }}">{% trans %}Create your third application{% endtrans %}</a></li>
</ul>
<h4>{% trans %}Full documentation{% endtrans %}</h4>
<ul>
<li><a href="http://wallabag.readthedocs.org">{% trans %}Convert your articles into ePUB or PDF{% endtrans %}</a></li>
<li><a href="http://wallabag.readthedocs.org">{% trans %}See how you can look for an article by using search engine and filters{% endtrans %}</a></li>
<li><a href="http://wallabag.readthedocs.org">{% trans %}And so many other articles!{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/en/v2/user/annotations.html">{% trans %}Annotate your article{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/en/v2/user/download_articles.html">{% trans %}Convert your articles into ePUB or PDF{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/en/v2/user/filters.html">{% trans %}See how you can look for an article by using search engine and filters{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/en/v2/user/errors_during_fetching.html">{% trans %}What can I do if an article encounters errors during fetching?{% endtrans %}</a></li>
<li><a href="http://doc.wallabag.org/">{% trans %}And so many other articles!{% endtrans %}</a></li>
</ul>
<h4>{% trans %}Support{% endtrans %}</h4>
<p>{% trans %}If you need some help, we are here for you.{% endtrans %}</p>

View File

@ -50,6 +50,7 @@
{% endif %}
<li class="bold {% if currentRoute == 'import' %}active{% endif %}"><a class="waves-effect" href="{{ path('import') }}">{% trans %}import{% endtrans %}</a></li>
<li class="bold {% if currentRoute == 'howto' %}active{% endif %}"><a class="waves-effect" href="{{ path('howto') }}">{% trans %}howto{% endtrans %}</a></li>
<li class="bold {% if currentRoute == 'developer' %}active{% endif %}"><a class="waves-effect" href="{{ path('developer') }}">{% trans %}Developer{% endtrans %}</a></li>
<li class="bold"><a class="waves-effect" class="icon icon-power" href="{{ path('fos_user_security_logout') }}" title="{% trans %}logout{% endtrans %}">{% trans %}logout{% endtrans %}</a></li>
</ul>
<div class="nav-wrapper nav-panels">

View File

@ -0,0 +1,71 @@
<?php
namespace Wallabag\CoreBundle\Tests\Controller;
use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
class DeveloperControllerTest extends WallabagCoreTestCase
{
public function testCreateClient()
{
$this->logInAs('admin');
$client = $this->getClient();
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
$nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
$crawler = $client->request('GET', '/developer/client/create');
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[type=submit]')->form();
$client->submit($form);
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
$this->assertGreaterThan(count($nbClients), count($newNbClients));
}
public function testListingClient()
{
$this->logInAs('admin');
$client = $this->getClient();
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
$nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
$crawler = $client->request('GET', '/developer');
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertEquals(count($nbClients), $crawler->filter('ul[class=collapsible] li')->count());
}
public function testDeveloperHowto()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/developer/howto/first-app');
$this->assertEquals(200, $client->getResponse()->getStatusCode());
}
public function testRemoveClient()
{
$this->logInAs('admin');
$client = $this->getClient();
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
$nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
$crawler = $client->request('GET', '/developer');
$link = $crawler
->filter('div[class=collapsible-body] p a')
->eq(0)
->link()
;
$client->click($link);
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
$this->assertGreaterThan(count($newNbClients), count($nbClients));
}
}

View File

@ -5,6 +5,8 @@ namespace Wallabag\ImportBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
class PocketController extends Controller
{
@ -13,21 +15,31 @@ class PocketController extends Controller
*/
public function indexAction()
{
$pocket = $this->get('wallabag_import.pocket.import');
$form = $this->createFormBuilder($pocket)
->add('read', CheckboxType::class, array(
'label' => 'Mark all as read',
'required' => false,
))
->getForm();
return $this->render('WallabagImportBundle:Pocket:index.html.twig', [
'import' => $this->get('wallabag_import.pocket.import'),
'has_consumer_key' => '' == trim($this->get('craue_config')->get('pocket_consumer_key')) ? false : true,
'form' => $form->createView(),
]);
}
/**
* @Route("/pocket/auth", name="import_pocket_auth")
*/
public function authAction()
public function authAction(Request $request)
{
$requestToken = $this->get('wallabag_import.pocket.import')
->getRequestToken($this->generateUrl('import', array(), UrlGeneratorInterface::ABSOLUTE_URL));
$this->get('session')->set('import.pocket.code', $requestToken);
$this->get('session')->set('read', $request->request->get('form')['read']);
return $this->redirect(
'https://getpocket.com/auth/authorize?request_token='.$requestToken.'&redirect_uri='.$this->generateUrl('import_pocket_callback', array(), UrlGeneratorInterface::ABSOLUTE_URL),
@ -42,6 +54,8 @@ class PocketController extends Controller
{
$message = 'Import failed, please try again.';
$pocket = $this->get('wallabag_import.pocket.import');
$markAsRead = $this->get('session')->get('read');
$this->get('session')->remove('read');
// something bad happend on pocket side
if (false === $pocket->authorize($this->get('session')->get('import.pocket.code'))) {
@ -53,7 +67,7 @@ class PocketController extends Controller
return $this->redirect($this->generateUrl('import_pocket'));
}
if (true === $pocket->import()) {
if (true === $pocket->setMarkAsRead($markAsRead)->import()) {
$summary = $pocket->getSummary();
$message = 'Import summary: '.$summary['imported'].' imported, '.$summary['skipped'].' already saved.';
}

View File

@ -21,15 +21,18 @@ class WallabagV1Controller extends Controller
if ($form->isValid()) {
$file = $form->get('file')->getData();
$markAsRead = $form->get('mark_as_read')->getData();
$name = $this->getUser()->getId().'.json';
if (in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes')) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
$res = $wallabag
->setUser($this->getUser())
->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name)
->setMarkAsRead($markAsRead)
->import();
$message = 'Import failed, please try again.';
if (true === $res) {
$summary = $wallabag->getSummary();
$message = 'Import summary: '.$summary['imported'].' imported, '.$summary['skipped'].' already saved.';

View File

@ -21,12 +21,14 @@ class WallabagV2Controller extends Controller
if ($form->isValid()) {
$file = $form->get('file')->getData();
$markAsRead = $form->get('mark_as_read')->getData();
$name = $this->getUser()->getId().'.json';
if (in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes')) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
$res = $wallabag
->setUser($this->getUser())
->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name)
->setMarkAsRead($markAsRead)
->import();
$message = 'Import failed, please try again.';

View File

@ -6,6 +6,7 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
class UploadImportType extends AbstractType
{
@ -13,6 +14,10 @@ class UploadImportType extends AbstractType
{
$builder
->add('file', FileType::class)
->add('mark_as_read', CheckboxType::class, array(
'label' => 'Mark all as read',
'required' => false,
))
->add('save', SubmitType::class)
;
}

View File

@ -22,6 +22,7 @@ class PocketImport implements ImportInterface
private $consumerKey;
private $skippedEntries = 0;
private $importedEntries = 0;
private $markAsRead;
protected $accessToken;
public function __construct(TokenStorageInterface $tokenStorage, EntityManager $em, ContentProxy $contentProxy, Config $craueConfig)
@ -123,6 +124,26 @@ class PocketImport implements ImportInterface
return true;
}
/**
* Set whether articles must be all marked as read.
*
* @param bool $markAsRead
*/
public function setMarkAsRead($markAsRead)
{
$this->markAsRead = $markAsRead;
return $this;
}
/**
* Get whether articles must be all marked as read.
*/
public function getRead()
{
return $this->markAsRead;
}
/**
* {@inheritdoc}
*/
@ -201,7 +222,7 @@ class PocketImport implements ImportInterface
$entry = $this->contentProxy->updateEntry($entry, $url);
// 0, 1, 2 - 1 if the item is archived - 2 if the item should be deleted
if ($pocketEntry['status'] == 1) {
if ($pocketEntry['status'] == 1 || $this->markAsRead) {
$entry->setArchived(true);
}

View File

@ -19,6 +19,7 @@ class WallabagV1Import implements ImportInterface
protected $skippedEntries = 0;
protected $importedEntries = 0;
protected $filepath;
protected $markAsRead;
public function __construct(EntityManager $em, ContentProxy $contentProxy)
{
@ -120,6 +121,18 @@ class WallabagV1Import implements ImportInterface
return $this;
}
/**
* Set whether articles must be all marked as read.
*
* @param bool $markAsRead
*/
public function setMarkAsRead($markAsRead)
{
$this->markAsRead = $markAsRead;
return $this;
}
/**
* @param $entries
*/
@ -160,7 +173,7 @@ class WallabagV1Import implements ImportInterface
);
}
$entry->setArchived($importedEntry['is_read']);
$entry->setArchived($importedEntry['is_read'] || $this->markAsRead);
$entry->setStarred($importedEntry['is_fav']);
$this->em->persist($entry);

View File

@ -51,7 +51,7 @@ class WallabagV2Import extends WallabagV1Import implements ImportInterface
$entry = new Entry($this->user);
$entry->setUrl($importedEntry['url']);
$entry->setTitle($importedEntry['title']);
$entry->setArchived($importedEntry['is_archived']);
$entry->setArchived($importedEntry['is_archived'] || $this->markAsRead);
$entry->setStarred($importedEntry['is_starred']);
$entry->setContent($importedEntry['content']);
$entry->setReadingTime($importedEntry['reading_time']);

View File

@ -19,6 +19,13 @@
<blockquote>{{ import.description|trans }}</blockquote>
<p>{% trans %}You can import your data from your Pocket account. You just have to click on the below button and authorize the application to connect to getpocket.com.{% endtrans %}</p>
<form method="post" action="{{ path('import_pocket_auth') }}">
<div class="row">
<div class="input-field col s6 with-checkbox">
<h6>{% trans %}Mark all as read ?{% endtrans %}</h6>
{{ form_widget(form.read) }}
<label for="form_read">{% trans %}Mark all imported entries as read{% endtrans %}</label>
</div>
</div>
<button class="btn waves-effect waves-light" type="submit" name="action">
{% trans %}Connect to Pocket and import data{% endtrans %}
</button>

View File

@ -22,6 +22,11 @@
<input class="file-path validate" type="text">
</div>
</div>
<div class="input-field col s6 with-checkbox">
<h6>{% trans %}Mark all as read ?{% endtrans %}</h6>
{{ form_widget(form.mark_as_read) }}
<label for="upload_import_file_mark_as_read">{% trans %}Mark all imported entries as read{% endtrans %}</label>
</div>
</div>
<div class="hidden">{{ form_rest(form) }}</div>
<button class="btn waves-effect waves-light" type="submit" name="action">

View File

@ -58,6 +58,50 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase
$this->assertContains('Import summary', $alert[0]);
}
public function testImportWallabagWithFileAndMarkAllAsRead()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/import/wallabag-v1');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__.'/../fixtures/wallabag-v1-read.json', 'wallabag-v1-read.json');
$data = array(
'upload_import_file[file]' => $file,
'upload_import_file[mark_as_read]' => 1,
);
$client->submit($form, $data);
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$content1 = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId(
'http://gilbert.pellegrom.me/recreating-the-square-slider',
$this->getLoggedInUserId()
);
$this->assertTrue($content1->isArchived());
$content2 = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId(
'https://www.wallabag.org/features/',
$this->getLoggedInUserId()
);
$this->assertTrue($content2->isArchived());
$this->assertContains('Import summary', $client->getResponse()->getContent());
}
public function testImportWallabagWithEmptyFile()
{
$this->logInAs('admin');

View File

@ -3,6 +3,7 @@
namespace Wallabag\ImportBundle\Tests\Import;
use Wallabag\UserBundle\Entity\User;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\ImportBundle\Import\PocketImport;
use GuzzleHttp\Client;
use GuzzleHttp\Subscriber\Mock;
@ -265,9 +266,7 @@ class PocketImportTest extends \PHPUnit_Framework_TestCase
->method('getRepository')
->willReturn($entryRepo);
$entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
->disableOriginalConstructor()
->getMock();
$entry = new Entry($this->user);
$this->contentProxy
->expects($this->once())
@ -283,6 +282,91 @@ class PocketImportTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(['skipped' => 1, 'imported' => 1], $pocketImport->getSummary());
}
/**
* Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
*/
public function testImportAndMarkAllAsRead()
{
$client = new Client();
$mock = new Mock([
new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
{
"status": 1,
"list": {
"229279689": {
"item_id": "229279689",
"resolved_id": "229279689",
"given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
"given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
"favorite": "1",
"status": "1",
"excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
"is_article": "1",
"has_video": "1",
"has_image": "1",
"word_count": "3197"
},
"229279690": {
"item_id": "229279689",
"resolved_id": "229279689",
"given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview/2",
"given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
"favorite": "1",
"status": "0",
"excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
"is_article": "1",
"has_video": "0",
"has_image": "0",
"word_count": "3197"
}
}
}
')),
]);
$client->getEmitter()->attach($mock);
$pocketImport = $this->getPocketImport();
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
->disableOriginalConstructor()
->getMock();
$entryRepo->expects($this->exactly(2))
->method('findByUrlAndUserId')
->will($this->onConsecutiveCalls(false, false));
$this->em
->expects($this->exactly(2))
->method('getRepository')
->willReturn($entryRepo);
// check that every entry persisted are archived
$this->em
->expects($this->any())
->method('persist')
->with($this->callback(function ($persistedEntry) {
return $persistedEntry->isArchived();
}));
$entry = new Entry($this->user);
$this->contentProxy
->expects($this->exactly(2))
->method('updateEntry')
->willReturn($entry);
$pocketImport->setClient($client);
$pocketImport->authorize('wunderbar_code');
$res = $pocketImport->setMarkAsRead(true)->import();
$this->assertTrue($res);
$this->assertEquals(['skipped' => 0, 'imported' => 2], $pocketImport->getSummary());
}
public function testImportBadResponse()
{
$client = new Client();

View File

@ -81,6 +81,39 @@ class WallabagV1ImportTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(['skipped' => 1, 'imported' => 3], $wallabagV1Import->getSummary());
}
public function testImportAndMarkAllAsRead()
{
$wallabagV1Import = $this->getWallabagV1Import();
$wallabagV1Import->setFilepath(__DIR__.'/../fixtures/wallabag-v1-read.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
->disableOriginalConstructor()
->getMock();
$entryRepo->expects($this->exactly(3))
->method('findByUrlAndUserId')
->will($this->onConsecutiveCalls(false, false, false));
$this->em
->expects($this->any())
->method('getRepository')
->willReturn($entryRepo);
// check that every entry persisted are archived
$this->em
->expects($this->any())
->method('persist')
->with($this->callback(function ($persistedEntry) {
return $persistedEntry->isArchived();
}));
$res = $wallabagV1Import->setMarkAsRead(true)->import();
$this->assertTrue($res);
$this->assertEquals(['skipped' => 0, 'imported' => 3], $wallabagV1Import->getSummary());
}
public function testImportBadFile()
{
$wallabagV1Import = $this->getWallabagV1Import();

View File

@ -72,6 +72,39 @@ class WallabagV2ImportTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(['skipped' => 1, 'imported' => 2], $wallabagV2Import->getSummary());
}
public function testImportAndMarkAllAsRead()
{
$wallabagV2Import = $this->getWallabagV2Import();
$wallabagV2Import->setFilepath(__DIR__.'/../fixtures/wallabag-v2-read.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
->disableOriginalConstructor()
->getMock();
$entryRepo->expects($this->exactly(2))
->method('findByUrlAndUserId')
->will($this->onConsecutiveCalls(false, false));
$this->em
->expects($this->any())
->method('getRepository')
->willReturn($entryRepo);
// check that every entry persisted are archived
$this->em
->expects($this->any())
->method('persist')
->with($this->callback(function ($persistedEntry) {
return $persistedEntry->isArchived();
}));
$res = $wallabagV2Import->setMarkAsRead(true)->import();
$this->assertTrue($res);
$this->assertEquals(['skipped' => 0, 'imported' => 2], $wallabagV2Import->getSummary());
}
public function testImportBadFile()
{
$wallabagV1Import = $this->getWallabagV2Import();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long