├── .gitignore ├── composer.json ├── README.md ├── zotero-remarkable.php └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .env 3 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "michaelmior/zotero-remarkable", 3 | "type": "project", 4 | "require": { 5 | "splitbrain/remarkable-api": "dev-master", 6 | "guzzlehttp/guzzle": "^6.3@dev", 7 | "chumper/zipper": "^1.0" 8 | }, 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Michael Mior", 13 | "email": "michael.mior@gmail.com" 14 | } 15 | ], 16 | "minimum-stability": "dev", 17 | "require-dev": { 18 | "vlucas/phpdotenv": "^2.5@dev" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zotero reMarkable sync 2 | 3 | This uses the reverse engineered [ReMarkable API](https://github.com/splitbrain/ReMarkableAPI) library to automatically transfer files from a Zotero collection to a reMarkable folder. 4 | When files have been uploaded, they are then removed from the Zotero collection. 5 | Run this script periodically to continually transfer uploaded files. 6 | 7 | Currently, the environment variables in the table below must be defined. 8 | You can use a [`.env` file](https://github.com/vlucas/phpdotenv) or define them any other way you choose. 9 | 10 | | Name | Description | 11 | |--------------------|----------------------------------------------------| 12 | |`ZOTERO_USER` | Zotero user ID | 13 | |`ZOTERO_API_KEY` | Zotero API key | 14 | |`ZOTERO_COLLECTION` | Collection key to use in Zotero | 15 | |`WEBDAV_URL` | URL of the WebDAV server hosting your Zotero files | 16 | |`WEBDAV_AUTH` | `username:password` for WebDAV authentication | 17 | |`REMARKABLE_TOKEN` | reMarkable API token | 18 | |`REMARKABLE_FOLDER` | reMarkable destination folder (default /Zotero) | 19 | 20 | Zotero user ID and API key can be found on the [settings](https://www.zotero.org/settings/keys) page. 21 | The Zotero collection key can be found as the last component in the URL path when browsing on the Web interface. 22 | For example in the URL below, the collection key is `ABCDEFG`. 23 | 24 | https://www.zotero.org/michaelmior/items/collectionKey/ABCDEFG 25 | 26 | The reMarkable API token is generated by [ReMarkable API](https://github.com/splitbrain/ReMarkableAPI). 27 | You will need a one-time code generated from [reMarkable](https://my.remarkable.com/). 28 | With the code, run `remarkable.php register YOUR_CODE_HERE`. 29 | This will generate a file `auth.token` which contains the key. 30 | -------------------------------------------------------------------------------- /zotero-remarkable.php: -------------------------------------------------------------------------------- 1 | load(); 25 | } 26 | 27 | $user = getenv('ZOTERO_USER'); 28 | $zoteroKey = getenv('ZOTERO_API_KEY'); 29 | $collection = getenv('ZOTERO_COLLECTION'); 30 | $webdavUrl = getenv('WEBDAV_URL'); 31 | $webdavAuth = getenv('WEBDAV_AUTH'); 32 | $reMarkableToken = getenv('REMARKABLE_TOKEN'); 33 | $reMarkableFolder = getenv('REMARKABLE_FOLDER'); 34 | if ($reMarkableFolder == FALSE) { 35 | $reMarkableFolder = "/Zotero"; 36 | } 37 | if ($reMarkableFolder[0] != "/") { 38 | $reMarkableFolder = "/" . $reMarkableFolder; 39 | } 40 | 41 | // Zotero API client 42 | $client = new GuzzleHttp\Client([ 43 | 'base_uri' => 'https://api.zotero.org/users/'. $user . '/', 44 | 'headers' => [ 45 | 'Zotero-API-Version' => 3, 46 | 'Zotero-API-Key' => $zoteroKey, 47 | 'Content-Type' => 'application/json' 48 | ] 49 | ]); 50 | 51 | echo "Fetching items from Zotero...\n"; 52 | 53 | $to_process = []; 54 | $titles = []; 55 | $collections = []; 56 | $versions = []; 57 | $response = $client->get('collections/' . $collection . '/items'); 58 | foreach (json_decode($response->getBody()) as $item) { 59 | // Store data to access parent info later 60 | $titles[$item->data->key] = $item->data->title; 61 | if (property_exists($item->data, 'collections')) { 62 | $collections[$item->data->key] = $item->data->collections; 63 | } 64 | $versions[$item->data->key] = $item->data->version; 65 | 66 | // Only upload PDF attachments 67 | if ($item->data->itemType == 'attachment' && $item->data->contentType == 'application/pdf') { 68 | $to_process[] = $item; 69 | } 70 | } 71 | 72 | echo count($to_process), " items found.\n"; 73 | 74 | // Stop if there is nothing to do 75 | if (count($to_process) == 0) { 76 | exit(0); 77 | } 78 | 79 | // WebDAV HTTP client for downloading zips 80 | $webDAVClient = new GuzzleHttp\Client([ 81 | 'base_uri' => $webdavUrl, 82 | 'auth' => explode(':', $webdavAuth) 83 | ]); 84 | 85 | $zipper = new \Chumper\Zipper\Zipper; 86 | $tmp_dir = sys_get_temp_dir(); 87 | 88 | $api = new RemarkableAPI(); 89 | $api->init($reMarkableToken); 90 | $fs = new RemarkableFS($api); 91 | $parent = $fs->mkdirP($reMarkableFolder); 92 | 93 | $to_remove = []; 94 | foreach ($to_process as $item) { 95 | echo 'Processing item ', $item->data->key, "\n"; 96 | 97 | // Store data for future removal 98 | $parentItem = $item->data->parentItem; 99 | if (!array_key_exists($parentItem, $titles)) { 100 | echo " Skipping since no parent was found!\n"; 101 | continue; 102 | } 103 | 104 | $title = $titles[$parentItem]; 105 | $to_remove[] = [ 106 | 'key' => $parentItem, 107 | 'version' => $versions[$parentItem], 108 | 'collections' => array_values(array_diff($collections[$parentItem], [$collection])) 109 | ]; 110 | 111 | // Download the zip file from WebDAV 112 | echo " Downloading zip...\n"; 113 | $zip_file = $item->data->key . '.zip'; 114 | $tmp_file = $tmp_dir . '/' . $zip_file; 115 | $zip_resp = $webDAVClient->get($zip_file, ['save_to' => $tmp_file]); 116 | 117 | // Extract the PDF 118 | echo " Extracting PDF...\n"; 119 | $zip = $zipper->make($tmp_file); 120 | $content = $zip->getFileContent($item->data->filename); 121 | 122 | // Upload to reMarkable and delete locally 123 | echo " Uploading to reMarkable...\n"; 124 | $api->uploadPDF($content, $title, $parent); 125 | unlink($tmp_file); 126 | 127 | echo ' Will update for deletion with ' . json_encode(end($to_remove)). "\n"; 128 | } 129 | 130 | // Remove the items from the collection 131 | echo "Removing items from Zotero collection...\n"; 132 | foreach (array_chunk($to_remove, 50) as $remove_chunk) { 133 | $client->post('items', ['body' => json_encode($remove_chunk)]); 134 | } 135 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "65fdf9a566fe25a2bc5045c964cf415f", 8 | "packages": [ 9 | { 10 | "name": "chumper/zipper", 11 | "version": "v1.0.2", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/Chumper/Zipper.git", 15 | "reference": "6a1733c34d67c3952b8439afb36ad4ea5c3ceacb" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/Chumper/Zipper/zipball/6a1733c34d67c3952b8439afb36ad4ea5c3ceacb", 20 | "reference": "6a1733c34d67c3952b8439afb36ad4ea5c3ceacb", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "illuminate/filesystem": "^5.0", 25 | "illuminate/support": "^5.0", 26 | "php": ">=5.6.0" 27 | }, 28 | "require-dev": { 29 | "mockery/mockery": "^0.9.4", 30 | "phpunit/phpunit": "^5.7" 31 | }, 32 | "type": "library", 33 | "extra": { 34 | "laravel": { 35 | "providers": [ 36 | "Chumper\\Zipper\\ZipperServiceProvider" 37 | ], 38 | "aliases": { 39 | "Zipper": "Chumper\\Zipper\\Zipper" 40 | } 41 | } 42 | }, 43 | "autoload": { 44 | "psr-4": { 45 | "Chumper\\Zipper\\": "src/Chumper/Zipper" 46 | } 47 | }, 48 | "notification-url": "https://packagist.org/downloads/", 49 | "license": [ 50 | "Apache2" 51 | ], 52 | "authors": [ 53 | { 54 | "name": "Nils Plaschke", 55 | "email": "github@nilsplaschke.de", 56 | "homepage": "http://nilsplaschke.de", 57 | "role": "Developer" 58 | } 59 | ], 60 | "description": "This is a little neat helper for the ZipArchive methods with handy functions", 61 | "homepage": "http://github.com/Chumper/zipper", 62 | "keywords": [ 63 | "archive", 64 | "laravel", 65 | "zip" 66 | ], 67 | "time": "2017-07-17T08:05:10+00:00" 68 | }, 69 | { 70 | "name": "doctrine/inflector", 71 | "version": "1.2.x-dev", 72 | "source": { 73 | "type": "git", 74 | "url": "https://github.com/doctrine/inflector.git", 75 | "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462" 76 | }, 77 | "dist": { 78 | "type": "zip", 79 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/e11d84c6e018beedd929cff5220969a3c6d1d462", 80 | "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462", 81 | "shasum": "" 82 | }, 83 | "require": { 84 | "php": "^7.0" 85 | }, 86 | "require-dev": { 87 | "phpunit/phpunit": "^6.2" 88 | }, 89 | "type": "library", 90 | "extra": { 91 | "branch-alias": { 92 | "dev-master": "1.2.x-dev" 93 | } 94 | }, 95 | "autoload": { 96 | "psr-4": { 97 | "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" 98 | } 99 | }, 100 | "notification-url": "https://packagist.org/downloads/", 101 | "license": [ 102 | "MIT" 103 | ], 104 | "authors": [ 105 | { 106 | "name": "Roman Borschel", 107 | "email": "roman@code-factory.org" 108 | }, 109 | { 110 | "name": "Benjamin Eberlei", 111 | "email": "kontakt@beberlei.de" 112 | }, 113 | { 114 | "name": "Guilherme Blanco", 115 | "email": "guilhermeblanco@gmail.com" 116 | }, 117 | { 118 | "name": "Jonathan Wage", 119 | "email": "jonwage@gmail.com" 120 | }, 121 | { 122 | "name": "Johannes Schmitt", 123 | "email": "schmittjoh@gmail.com" 124 | } 125 | ], 126 | "description": "Common String Manipulations with regard to casing and singular/plural rules.", 127 | "homepage": "http://www.doctrine-project.org", 128 | "keywords": [ 129 | "inflection", 130 | "pluralize", 131 | "singularize", 132 | "string" 133 | ], 134 | "time": "2017-07-22T12:18:28+00:00" 135 | }, 136 | { 137 | "name": "guzzlehttp/guzzle", 138 | "version": "dev-master", 139 | "source": { 140 | "type": "git", 141 | "url": "https://github.com/guzzle/guzzle.git", 142 | "reference": "ba1bce30baab94dddde21c4ae93872b1762d39fa" 143 | }, 144 | "dist": { 145 | "type": "zip", 146 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ba1bce30baab94dddde21c4ae93872b1762d39fa", 147 | "reference": "ba1bce30baab94dddde21c4ae93872b1762d39fa", 148 | "shasum": "" 149 | }, 150 | "require": { 151 | "guzzlehttp/promises": "^1.0", 152 | "guzzlehttp/psr7": "^1.4", 153 | "php": ">=5.5" 154 | }, 155 | "require-dev": { 156 | "ext-curl": "*", 157 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4", 158 | "psr/log": "^1.0" 159 | }, 160 | "suggest": { 161 | "psr/log": "Required for using the Log middleware" 162 | }, 163 | "type": "library", 164 | "extra": { 165 | "branch-alias": { 166 | "dev-master": "6.3-dev" 167 | } 168 | }, 169 | "autoload": { 170 | "files": [ 171 | "src/functions_include.php" 172 | ], 173 | "psr-4": { 174 | "GuzzleHttp\\": "src/" 175 | } 176 | }, 177 | "notification-url": "https://packagist.org/downloads/", 178 | "license": [ 179 | "MIT" 180 | ], 181 | "authors": [ 182 | { 183 | "name": "Michael Dowling", 184 | "email": "mtdowling@gmail.com", 185 | "homepage": "https://github.com/mtdowling" 186 | } 187 | ], 188 | "description": "Guzzle is a PHP HTTP client library", 189 | "homepage": "http://guzzlephp.org/", 190 | "keywords": [ 191 | "client", 192 | "curl", 193 | "framework", 194 | "http", 195 | "http client", 196 | "rest", 197 | "web service" 198 | ], 199 | "time": "2018-03-11T15:03:34+00:00" 200 | }, 201 | { 202 | "name": "guzzlehttp/promises", 203 | "version": "dev-master", 204 | "source": { 205 | "type": "git", 206 | "url": "https://github.com/guzzle/promises.git", 207 | "reference": "0940c910fd14a68bd24a8b7c4a5528415a479c42" 208 | }, 209 | "dist": { 210 | "type": "zip", 211 | "url": "https://api.github.com/repos/guzzle/promises/zipball/0940c910fd14a68bd24a8b7c4a5528415a479c42", 212 | "reference": "0940c910fd14a68bd24a8b7c4a5528415a479c42", 213 | "shasum": "" 214 | }, 215 | "require": { 216 | "php": ">=5.5.0" 217 | }, 218 | "require-dev": { 219 | "phpunit/phpunit": "^4.8.36" 220 | }, 221 | "type": "library", 222 | "extra": { 223 | "branch-alias": { 224 | "dev-master": "1.4-dev" 225 | } 226 | }, 227 | "autoload": { 228 | "psr-4": { 229 | "GuzzleHttp\\Promise\\": "src/" 230 | }, 231 | "files": [ 232 | "src/functions_include.php" 233 | ] 234 | }, 235 | "notification-url": "https://packagist.org/downloads/", 236 | "license": [ 237 | "MIT" 238 | ], 239 | "authors": [ 240 | { 241 | "name": "Michael Dowling", 242 | "email": "mtdowling@gmail.com", 243 | "homepage": "https://github.com/mtdowling" 244 | } 245 | ], 246 | "description": "Guzzle promises library", 247 | "keywords": [ 248 | "promise" 249 | ], 250 | "time": "2018-02-28T07:24:33+00:00" 251 | }, 252 | { 253 | "name": "guzzlehttp/psr7", 254 | "version": "dev-master", 255 | "source": { 256 | "type": "git", 257 | "url": "https://github.com/guzzle/psr7.git", 258 | "reference": "649e354b657977c312cb6fb95720b1ac485f2092" 259 | }, 260 | "dist": { 261 | "type": "zip", 262 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/649e354b657977c312cb6fb95720b1ac485f2092", 263 | "reference": "649e354b657977c312cb6fb95720b1ac485f2092", 264 | "shasum": "" 265 | }, 266 | "require": { 267 | "php": ">=5.4.0", 268 | "psr/http-message": "~1.0" 269 | }, 270 | "provide": { 271 | "psr/http-message-implementation": "1.0" 272 | }, 273 | "require-dev": { 274 | "phpunit/phpunit": "~4.0" 275 | }, 276 | "type": "library", 277 | "extra": { 278 | "branch-alias": { 279 | "dev-master": "1.4-dev" 280 | } 281 | }, 282 | "autoload": { 283 | "psr-4": { 284 | "GuzzleHttp\\Psr7\\": "src/" 285 | }, 286 | "files": [ 287 | "src/functions_include.php" 288 | ] 289 | }, 290 | "notification-url": "https://packagist.org/downloads/", 291 | "license": [ 292 | "MIT" 293 | ], 294 | "authors": [ 295 | { 296 | "name": "Michael Dowling", 297 | "email": "mtdowling@gmail.com", 298 | "homepage": "https://github.com/mtdowling" 299 | }, 300 | { 301 | "name": "Tobias Schultze", 302 | "homepage": "https://github.com/Tobion" 303 | } 304 | ], 305 | "description": "PSR-7 message implementation that also provides common utility methods", 306 | "keywords": [ 307 | "http", 308 | "message", 309 | "request", 310 | "response", 311 | "stream", 312 | "uri", 313 | "url" 314 | ], 315 | "time": "2018-02-28T07:24:56+00:00" 316 | }, 317 | { 318 | "name": "illuminate/contracts", 319 | "version": "5.5.x-dev", 320 | "source": { 321 | "type": "git", 322 | "url": "https://github.com/illuminate/contracts.git", 323 | "reference": "eb9a0171866fca0669c9acab6c7441e19b4694ca" 324 | }, 325 | "dist": { 326 | "type": "zip", 327 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/eb9a0171866fca0669c9acab6c7441e19b4694ca", 328 | "reference": "eb9a0171866fca0669c9acab6c7441e19b4694ca", 329 | "shasum": "" 330 | }, 331 | "require": { 332 | "php": ">=7.0", 333 | "psr/container": "~1.0", 334 | "psr/simple-cache": "~1.0" 335 | }, 336 | "type": "library", 337 | "extra": { 338 | "branch-alias": { 339 | "dev-master": "5.5-dev" 340 | } 341 | }, 342 | "autoload": { 343 | "psr-4": { 344 | "Illuminate\\Contracts\\": "" 345 | } 346 | }, 347 | "notification-url": "https://packagist.org/downloads/", 348 | "license": [ 349 | "MIT" 350 | ], 351 | "authors": [ 352 | { 353 | "name": "Taylor Otwell", 354 | "email": "taylor@laravel.com" 355 | } 356 | ], 357 | "description": "The Illuminate Contracts package.", 358 | "homepage": "https://laravel.com", 359 | "time": "2018-01-19T17:59:58+00:00" 360 | }, 361 | { 362 | "name": "illuminate/filesystem", 363 | "version": "5.5.x-dev", 364 | "source": { 365 | "type": "git", 366 | "url": "https://github.com/illuminate/filesystem.git", 367 | "reference": "31921ef731567fc0b80c110437a028ae8a3add13" 368 | }, 369 | "dist": { 370 | "type": "zip", 371 | "url": "https://api.github.com/repos/illuminate/filesystem/zipball/31921ef731567fc0b80c110437a028ae8a3add13", 372 | "reference": "31921ef731567fc0b80c110437a028ae8a3add13", 373 | "shasum": "" 374 | }, 375 | "require": { 376 | "illuminate/contracts": "5.5.*", 377 | "illuminate/support": "5.5.*", 378 | "php": ">=7.0", 379 | "symfony/finder": "~3.3" 380 | }, 381 | "suggest": { 382 | "league/flysystem": "Required to use the Flysystem local and FTP drivers (~1.0).", 383 | "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", 384 | "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0)." 385 | }, 386 | "type": "library", 387 | "extra": { 388 | "branch-alias": { 389 | "dev-master": "5.5-dev" 390 | } 391 | }, 392 | "autoload": { 393 | "psr-4": { 394 | "Illuminate\\Filesystem\\": "" 395 | } 396 | }, 397 | "notification-url": "https://packagist.org/downloads/", 398 | "license": [ 399 | "MIT" 400 | ], 401 | "authors": [ 402 | { 403 | "name": "Taylor Otwell", 404 | "email": "taylor@laravel.com" 405 | } 406 | ], 407 | "description": "The Illuminate Filesystem package.", 408 | "homepage": "https://laravel.com", 409 | "time": "2018-02-07T00:04:00+00:00" 410 | }, 411 | { 412 | "name": "illuminate/support", 413 | "version": "5.5.x-dev", 414 | "source": { 415 | "type": "git", 416 | "url": "https://github.com/illuminate/support.git", 417 | "reference": "5d2ccb17e526ad537bffc16abc1d516457ae5587" 418 | }, 419 | "dist": { 420 | "type": "zip", 421 | "url": "https://api.github.com/repos/illuminate/support/zipball/5d2ccb17e526ad537bffc16abc1d516457ae5587", 422 | "reference": "5d2ccb17e526ad537bffc16abc1d516457ae5587", 423 | "shasum": "" 424 | }, 425 | "require": { 426 | "doctrine/inflector": "~1.1", 427 | "ext-mbstring": "*", 428 | "illuminate/contracts": "5.5.*", 429 | "nesbot/carbon": "^1.24.1", 430 | "php": ">=7.0" 431 | }, 432 | "replace": { 433 | "tightenco/collect": "<5.5.33" 434 | }, 435 | "suggest": { 436 | "illuminate/filesystem": "Required to use the composer class (5.5.*).", 437 | "symfony/process": "Required to use the composer class (~3.3).", 438 | "symfony/var-dumper": "Required to use the dd function (~3.3)." 439 | }, 440 | "type": "library", 441 | "extra": { 442 | "branch-alias": { 443 | "dev-master": "5.5-dev" 444 | } 445 | }, 446 | "autoload": { 447 | "psr-4": { 448 | "Illuminate\\Support\\": "" 449 | }, 450 | "files": [ 451 | "helpers.php" 452 | ] 453 | }, 454 | "notification-url": "https://packagist.org/downloads/", 455 | "license": [ 456 | "MIT" 457 | ], 458 | "authors": [ 459 | { 460 | "name": "Taylor Otwell", 461 | "email": "taylor@laravel.com" 462 | } 463 | ], 464 | "description": "The Illuminate Support package.", 465 | "homepage": "https://laravel.com", 466 | "time": "2018-03-10T15:44:32+00:00" 467 | }, 468 | { 469 | "name": "nesbot/carbon", 470 | "version": "1.24.2", 471 | "source": { 472 | "type": "git", 473 | "url": "https://github.com/briannesbitt/Carbon.git", 474 | "reference": "bba6c6e410c6b4317e37a9474aeaa753808c3875" 475 | }, 476 | "dist": { 477 | "type": "zip", 478 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bba6c6e410c6b4317e37a9474aeaa753808c3875", 479 | "reference": "bba6c6e410c6b4317e37a9474aeaa753808c3875", 480 | "shasum": "" 481 | }, 482 | "require": { 483 | "php": ">=5.3.9", 484 | "symfony/translation": "~2.6 || ~3.0 || ~4.0" 485 | }, 486 | "require-dev": { 487 | "friendsofphp/php-cs-fixer": "~2", 488 | "phpunit/phpunit": "^4.8.35 || ^5.7" 489 | }, 490 | "type": "library", 491 | "extra": { 492 | "branch-alias": { 493 | "dev-master": "1.23-dev" 494 | } 495 | }, 496 | "autoload": { 497 | "psr-4": { 498 | "Carbon\\": "src/Carbon/" 499 | } 500 | }, 501 | "notification-url": "https://packagist.org/downloads/", 502 | "license": [ 503 | "MIT" 504 | ], 505 | "authors": [ 506 | { 507 | "name": "Brian Nesbitt", 508 | "email": "brian@nesbot.com", 509 | "homepage": "http://nesbot.com" 510 | } 511 | ], 512 | "description": "A simple API extension for DateTime.", 513 | "homepage": "http://carbon.nesbot.com", 514 | "keywords": [ 515 | "date", 516 | "datetime", 517 | "time" 518 | ], 519 | "time": "2018-03-10T10:10:14+00:00" 520 | }, 521 | { 522 | "name": "paragonie/random_compat", 523 | "version": "v2.0.11", 524 | "source": { 525 | "type": "git", 526 | "url": "https://github.com/paragonie/random_compat.git", 527 | "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" 528 | }, 529 | "dist": { 530 | "type": "zip", 531 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", 532 | "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", 533 | "shasum": "" 534 | }, 535 | "require": { 536 | "php": ">=5.2.0" 537 | }, 538 | "require-dev": { 539 | "phpunit/phpunit": "4.*|5.*" 540 | }, 541 | "suggest": { 542 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." 543 | }, 544 | "type": "library", 545 | "autoload": { 546 | "files": [ 547 | "lib/random.php" 548 | ] 549 | }, 550 | "notification-url": "https://packagist.org/downloads/", 551 | "license": [ 552 | "MIT" 553 | ], 554 | "authors": [ 555 | { 556 | "name": "Paragon Initiative Enterprises", 557 | "email": "security@paragonie.com", 558 | "homepage": "https://paragonie.com" 559 | } 560 | ], 561 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", 562 | "keywords": [ 563 | "csprng", 564 | "pseudorandom", 565 | "random" 566 | ], 567 | "time": "2017-09-27T21:40:39+00:00" 568 | }, 569 | { 570 | "name": "psr/container", 571 | "version": "dev-master", 572 | "source": { 573 | "type": "git", 574 | "url": "https://github.com/php-fig/container.git", 575 | "reference": "2cc4a01788191489dc7459446ba832fa79a216a7" 576 | }, 577 | "dist": { 578 | "type": "zip", 579 | "url": "https://api.github.com/repos/php-fig/container/zipball/2cc4a01788191489dc7459446ba832fa79a216a7", 580 | "reference": "2cc4a01788191489dc7459446ba832fa79a216a7", 581 | "shasum": "" 582 | }, 583 | "require": { 584 | "php": ">=5.3.0" 585 | }, 586 | "type": "library", 587 | "extra": { 588 | "branch-alias": { 589 | "dev-master": "1.0.x-dev" 590 | } 591 | }, 592 | "autoload": { 593 | "psr-4": { 594 | "Psr\\Container\\": "src/" 595 | } 596 | }, 597 | "notification-url": "https://packagist.org/downloads/", 598 | "license": [ 599 | "MIT" 600 | ], 601 | "authors": [ 602 | { 603 | "name": "PHP-FIG", 604 | "homepage": "http://www.php-fig.org/" 605 | } 606 | ], 607 | "description": "Common Container Interface (PHP FIG PSR-11)", 608 | "homepage": "https://github.com/php-fig/container", 609 | "keywords": [ 610 | "PSR-11", 611 | "container", 612 | "container-interface", 613 | "container-interop", 614 | "psr" 615 | ], 616 | "time": "2017-06-28T15:35:32+00:00" 617 | }, 618 | { 619 | "name": "psr/http-message", 620 | "version": "dev-master", 621 | "source": { 622 | "type": "git", 623 | "url": "https://github.com/php-fig/http-message.git", 624 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 625 | }, 626 | "dist": { 627 | "type": "zip", 628 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 629 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 630 | "shasum": "" 631 | }, 632 | "require": { 633 | "php": ">=5.3.0" 634 | }, 635 | "type": "library", 636 | "extra": { 637 | "branch-alias": { 638 | "dev-master": "1.0.x-dev" 639 | } 640 | }, 641 | "autoload": { 642 | "psr-4": { 643 | "Psr\\Http\\Message\\": "src/" 644 | } 645 | }, 646 | "notification-url": "https://packagist.org/downloads/", 647 | "license": [ 648 | "MIT" 649 | ], 650 | "authors": [ 651 | { 652 | "name": "PHP-FIG", 653 | "homepage": "http://www.php-fig.org/" 654 | } 655 | ], 656 | "description": "Common interface for HTTP messages", 657 | "homepage": "https://github.com/php-fig/http-message", 658 | "keywords": [ 659 | "http", 660 | "http-message", 661 | "psr", 662 | "psr-7", 663 | "request", 664 | "response" 665 | ], 666 | "time": "2016-08-06T14:39:51+00:00" 667 | }, 668 | { 669 | "name": "psr/log", 670 | "version": "dev-master", 671 | "source": { 672 | "type": "git", 673 | "url": "https://github.com/php-fig/log.git", 674 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 675 | }, 676 | "dist": { 677 | "type": "zip", 678 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 679 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 680 | "shasum": "" 681 | }, 682 | "require": { 683 | "php": ">=5.3.0" 684 | }, 685 | "type": "library", 686 | "extra": { 687 | "branch-alias": { 688 | "dev-master": "1.0.x-dev" 689 | } 690 | }, 691 | "autoload": { 692 | "psr-4": { 693 | "Psr\\Log\\": "Psr/Log/" 694 | } 695 | }, 696 | "notification-url": "https://packagist.org/downloads/", 697 | "license": [ 698 | "MIT" 699 | ], 700 | "authors": [ 701 | { 702 | "name": "PHP-FIG", 703 | "homepage": "http://www.php-fig.org/" 704 | } 705 | ], 706 | "description": "Common interface for logging libraries", 707 | "homepage": "https://github.com/php-fig/log", 708 | "keywords": [ 709 | "log", 710 | "psr", 711 | "psr-3" 712 | ], 713 | "time": "2016-10-10T12:19:37+00:00" 714 | }, 715 | { 716 | "name": "psr/simple-cache", 717 | "version": "dev-master", 718 | "source": { 719 | "type": "git", 720 | "url": "https://github.com/php-fig/simple-cache.git", 721 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" 722 | }, 723 | "dist": { 724 | "type": "zip", 725 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 726 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 727 | "shasum": "" 728 | }, 729 | "require": { 730 | "php": ">=5.3.0" 731 | }, 732 | "type": "library", 733 | "extra": { 734 | "branch-alias": { 735 | "dev-master": "1.0.x-dev" 736 | } 737 | }, 738 | "autoload": { 739 | "psr-4": { 740 | "Psr\\SimpleCache\\": "src/" 741 | } 742 | }, 743 | "notification-url": "https://packagist.org/downloads/", 744 | "license": [ 745 | "MIT" 746 | ], 747 | "authors": [ 748 | { 749 | "name": "PHP-FIG", 750 | "homepage": "http://www.php-fig.org/" 751 | } 752 | ], 753 | "description": "Common interfaces for simple caching", 754 | "keywords": [ 755 | "cache", 756 | "caching", 757 | "psr", 758 | "psr-16", 759 | "simple-cache" 760 | ], 761 | "time": "2017-10-23T01:57:42+00:00" 762 | }, 763 | { 764 | "name": "ramsey/uuid", 765 | "version": "dev-master", 766 | "source": { 767 | "type": "git", 768 | "url": "https://github.com/ramsey/uuid.git", 769 | "reference": "62628862df4c7b6568630d23f403bc42436d7c5e" 770 | }, 771 | "dist": { 772 | "type": "zip", 773 | "url": "https://api.github.com/repos/ramsey/uuid/zipball/62628862df4c7b6568630d23f403bc42436d7c5e", 774 | "reference": "62628862df4c7b6568630d23f403bc42436d7c5e", 775 | "shasum": "" 776 | }, 777 | "require": { 778 | "paragonie/random_compat": "^1.0|^2.0", 779 | "php": "^5.4 || ^7.0" 780 | }, 781 | "replace": { 782 | "rhumsaa/uuid": "self.version" 783 | }, 784 | "require-dev": { 785 | "codeception/aspect-mock": "^1.0 | ~2.0.0", 786 | "doctrine/annotations": "~1.2.0", 787 | "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ^2.1", 788 | "ircmaxell/random-lib": "^1.1", 789 | "jakub-onderka/php-parallel-lint": "^0.9.0", 790 | "mockery/mockery": "^0.9.9", 791 | "moontoast/math": "^1.1", 792 | "php-mock/php-mock-phpunit": "^0.3|^1.1", 793 | "phpunit/phpunit": "^4.7|^5.0", 794 | "squizlabs/php_codesniffer": "^2.3" 795 | }, 796 | "suggest": { 797 | "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", 798 | "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", 799 | "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", 800 | "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", 801 | "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", 802 | "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." 803 | }, 804 | "type": "library", 805 | "extra": { 806 | "branch-alias": { 807 | "dev-master": "3.x-dev" 808 | } 809 | }, 810 | "autoload": { 811 | "psr-4": { 812 | "Ramsey\\Uuid\\": "src/" 813 | } 814 | }, 815 | "notification-url": "https://packagist.org/downloads/", 816 | "license": [ 817 | "MIT" 818 | ], 819 | "authors": [ 820 | { 821 | "name": "Marijn Huizendveld", 822 | "email": "marijn.huizendveld@gmail.com" 823 | }, 824 | { 825 | "name": "Thibaud Fabre", 826 | "email": "thibaud@aztech.io" 827 | }, 828 | { 829 | "name": "Ben Ramsey", 830 | "email": "ben@benramsey.com", 831 | "homepage": "https://benramsey.com" 832 | } 833 | ], 834 | "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", 835 | "homepage": "https://github.com/ramsey/uuid", 836 | "keywords": [ 837 | "guid", 838 | "identifier", 839 | "uuid" 840 | ], 841 | "time": "2018-02-07T23:28:02+00:00" 842 | }, 843 | { 844 | "name": "splitbrain/php-archive", 845 | "version": "1.0.9", 846 | "source": { 847 | "type": "git", 848 | "url": "https://github.com/splitbrain/php-archive.git", 849 | "reference": "2a63b8cf0bfc7fdc0d987c9b7348e639e55cce76" 850 | }, 851 | "dist": { 852 | "type": "zip", 853 | "url": "https://api.github.com/repos/splitbrain/php-archive/zipball/2a63b8cf0bfc7fdc0d987c9b7348e639e55cce76", 854 | "reference": "2a63b8cf0bfc7fdc0d987c9b7348e639e55cce76", 855 | "shasum": "" 856 | }, 857 | "require": { 858 | "php": ">=5.3.0" 859 | }, 860 | "require-dev": { 861 | "phpunit/phpunit": "4.5.*" 862 | }, 863 | "suggest": { 864 | "ext-iconv": "Used for proper filename encode handling", 865 | "ext-mbstring": "Can be used alternatively for handling filename encoding" 866 | }, 867 | "type": "library", 868 | "autoload": { 869 | "psr-4": { 870 | "splitbrain\\PHPArchive\\": "src" 871 | } 872 | }, 873 | "notification-url": "https://packagist.org/downloads/", 874 | "license": [ 875 | "MIT" 876 | ], 877 | "authors": [ 878 | { 879 | "name": "Andreas Gohr", 880 | "email": "andi@splitbrain.org" 881 | } 882 | ], 883 | "description": "Pure-PHP implementation to read and write TAR and ZIP archives", 884 | "keywords": [ 885 | "archive", 886 | "extract", 887 | "tar", 888 | "unpack", 889 | "unzip", 890 | "zip" 891 | ], 892 | "time": "2017-06-11T06:11:38+00:00" 893 | }, 894 | { 895 | "name": "splitbrain/remarkable-api", 896 | "version": "dev-master", 897 | "source": { 898 | "type": "git", 899 | "url": "https://github.com/splitbrain/ReMarkableAPI.git", 900 | "reference": "d33f4632b91bc2465ea8fcf0b2c41dcb675c8d12" 901 | }, 902 | "dist": { 903 | "type": "zip", 904 | "url": "https://api.github.com/repos/splitbrain/ReMarkableAPI/zipball/d33f4632b91bc2465ea8fcf0b2c41dcb675c8d12", 905 | "reference": "d33f4632b91bc2465ea8fcf0b2c41dcb675c8d12", 906 | "shasum": "" 907 | }, 908 | "require": { 909 | "guzzlehttp/guzzle": "^6.3", 910 | "psr/log": "^1.0", 911 | "ramsey/uuid": "^3.7", 912 | "splitbrain/php-archive": "^1.0" 913 | }, 914 | "require-dev": { 915 | "splitbrain/php-cli": "^1.1" 916 | }, 917 | "type": "library", 918 | "autoload": { 919 | "psr-4": { 920 | "splitbrain\\RemarkableAPI\\": "src" 921 | } 922 | }, 923 | "notification-url": "https://packagist.org/downloads/", 924 | "license": [ 925 | "MIT" 926 | ], 927 | "authors": [ 928 | { 929 | "name": "Andreas Gohr", 930 | "email": "andi@splitbrain.org" 931 | } 932 | ], 933 | "description": "PHP Implementation of the reMarkable file API", 934 | "time": "2018-03-10T05:57:19+00:00" 935 | }, 936 | { 937 | "name": "symfony/finder", 938 | "version": "3.4.x-dev", 939 | "source": { 940 | "type": "git", 941 | "url": "https://github.com/symfony/finder.git", 942 | "reference": "a479817ce0a9e4adfd7d39c6407c95d97c254625" 943 | }, 944 | "dist": { 945 | "type": "zip", 946 | "url": "https://api.github.com/repos/symfony/finder/zipball/a479817ce0a9e4adfd7d39c6407c95d97c254625", 947 | "reference": "a479817ce0a9e4adfd7d39c6407c95d97c254625", 948 | "shasum": "" 949 | }, 950 | "require": { 951 | "php": "^5.5.9|>=7.0.8" 952 | }, 953 | "type": "library", 954 | "extra": { 955 | "branch-alias": { 956 | "dev-master": "3.4-dev" 957 | } 958 | }, 959 | "autoload": { 960 | "psr-4": { 961 | "Symfony\\Component\\Finder\\": "" 962 | }, 963 | "exclude-from-classmap": [ 964 | "/Tests/" 965 | ] 966 | }, 967 | "notification-url": "https://packagist.org/downloads/", 968 | "license": [ 969 | "MIT" 970 | ], 971 | "authors": [ 972 | { 973 | "name": "Fabien Potencier", 974 | "email": "fabien@symfony.com" 975 | }, 976 | { 977 | "name": "Symfony Community", 978 | "homepage": "https://symfony.com/contributors" 979 | } 980 | ], 981 | "description": "Symfony Finder Component", 982 | "homepage": "https://symfony.com", 983 | "time": "2018-03-05T18:28:11+00:00" 984 | }, 985 | { 986 | "name": "symfony/polyfill-mbstring", 987 | "version": "dev-master", 988 | "source": { 989 | "type": "git", 990 | "url": "https://github.com/symfony/polyfill-mbstring.git", 991 | "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" 992 | }, 993 | "dist": { 994 | "type": "zip", 995 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", 996 | "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", 997 | "shasum": "" 998 | }, 999 | "require": { 1000 | "php": ">=5.3.3" 1001 | }, 1002 | "suggest": { 1003 | "ext-mbstring": "For best performance" 1004 | }, 1005 | "type": "library", 1006 | "extra": { 1007 | "branch-alias": { 1008 | "dev-master": "1.7-dev" 1009 | } 1010 | }, 1011 | "autoload": { 1012 | "psr-4": { 1013 | "Symfony\\Polyfill\\Mbstring\\": "" 1014 | }, 1015 | "files": [ 1016 | "bootstrap.php" 1017 | ] 1018 | }, 1019 | "notification-url": "https://packagist.org/downloads/", 1020 | "license": [ 1021 | "MIT" 1022 | ], 1023 | "authors": [ 1024 | { 1025 | "name": "Nicolas Grekas", 1026 | "email": "p@tchwork.com" 1027 | }, 1028 | { 1029 | "name": "Symfony Community", 1030 | "homepage": "https://symfony.com/contributors" 1031 | } 1032 | ], 1033 | "description": "Symfony polyfill for the Mbstring extension", 1034 | "homepage": "https://symfony.com", 1035 | "keywords": [ 1036 | "compatibility", 1037 | "mbstring", 1038 | "polyfill", 1039 | "portable", 1040 | "shim" 1041 | ], 1042 | "time": "2018-01-30T19:27:44+00:00" 1043 | }, 1044 | { 1045 | "name": "symfony/translation", 1046 | "version": "3.4.x-dev", 1047 | "source": { 1048 | "type": "git", 1049 | "url": "https://github.com/symfony/translation.git", 1050 | "reference": "80e19eaf12cbb546ac40384e5c55c36306823e57" 1051 | }, 1052 | "dist": { 1053 | "type": "zip", 1054 | "url": "https://api.github.com/repos/symfony/translation/zipball/80e19eaf12cbb546ac40384e5c55c36306823e57", 1055 | "reference": "80e19eaf12cbb546ac40384e5c55c36306823e57", 1056 | "shasum": "" 1057 | }, 1058 | "require": { 1059 | "php": "^5.5.9|>=7.0.8", 1060 | "symfony/polyfill-mbstring": "~1.0" 1061 | }, 1062 | "conflict": { 1063 | "symfony/config": "<2.8", 1064 | "symfony/dependency-injection": "<3.4", 1065 | "symfony/yaml": "<3.4" 1066 | }, 1067 | "require-dev": { 1068 | "psr/log": "~1.0", 1069 | "symfony/config": "~2.8|~3.0|~4.0", 1070 | "symfony/dependency-injection": "~3.4|~4.0", 1071 | "symfony/finder": "~2.8|~3.0|~4.0", 1072 | "symfony/intl": "^2.8.18|^3.2.5|~4.0", 1073 | "symfony/yaml": "~3.4|~4.0" 1074 | }, 1075 | "suggest": { 1076 | "psr/log": "To use logging capability in translator", 1077 | "symfony/config": "", 1078 | "symfony/yaml": "" 1079 | }, 1080 | "type": "library", 1081 | "extra": { 1082 | "branch-alias": { 1083 | "dev-master": "3.4-dev" 1084 | } 1085 | }, 1086 | "autoload": { 1087 | "psr-4": { 1088 | "Symfony\\Component\\Translation\\": "" 1089 | }, 1090 | "exclude-from-classmap": [ 1091 | "/Tests/" 1092 | ] 1093 | }, 1094 | "notification-url": "https://packagist.org/downloads/", 1095 | "license": [ 1096 | "MIT" 1097 | ], 1098 | "authors": [ 1099 | { 1100 | "name": "Fabien Potencier", 1101 | "email": "fabien@symfony.com" 1102 | }, 1103 | { 1104 | "name": "Symfony Community", 1105 | "homepage": "https://symfony.com/contributors" 1106 | } 1107 | ], 1108 | "description": "Symfony Translation Component", 1109 | "homepage": "https://symfony.com", 1110 | "time": "2018-02-22T06:28:18+00:00" 1111 | } 1112 | ], 1113 | "packages-dev": [ 1114 | { 1115 | "name": "vlucas/phpdotenv", 1116 | "version": "dev-master", 1117 | "source": { 1118 | "type": "git", 1119 | "url": "https://github.com/vlucas/phpdotenv.git", 1120 | "reference": "90b2f4112475578eb60269266e79514e1b4128b6" 1121 | }, 1122 | "dist": { 1123 | "type": "zip", 1124 | "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/90b2f4112475578eb60269266e79514e1b4128b6", 1125 | "reference": "90b2f4112475578eb60269266e79514e1b4128b6", 1126 | "shasum": "" 1127 | }, 1128 | "require": { 1129 | "php": ">=5.3.9" 1130 | }, 1131 | "require-dev": { 1132 | "phpunit/phpunit": "^4.8.35 || ^5.0" 1133 | }, 1134 | "type": "library", 1135 | "extra": { 1136 | "branch-alias": { 1137 | "dev-master": "2.5-dev" 1138 | } 1139 | }, 1140 | "autoload": { 1141 | "psr-4": { 1142 | "Dotenv\\": "src/" 1143 | } 1144 | }, 1145 | "notification-url": "https://packagist.org/downloads/", 1146 | "license": [ 1147 | "BSD-3-Clause-Attribution" 1148 | ], 1149 | "authors": [ 1150 | { 1151 | "name": "Vance Lucas", 1152 | "email": "vance@vancelucas.com", 1153 | "homepage": "http://www.vancelucas.com" 1154 | } 1155 | ], 1156 | "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", 1157 | "keywords": [ 1158 | "dotenv", 1159 | "env", 1160 | "environment" 1161 | ], 1162 | "time": "2018-01-28T23:08:18+00:00" 1163 | } 1164 | ], 1165 | "aliases": [], 1166 | "minimum-stability": "dev", 1167 | "stability-flags": { 1168 | "splitbrain/remarkable-api": 20, 1169 | "guzzlehttp/guzzle": 20, 1170 | "vlucas/phpdotenv": 20 1171 | }, 1172 | "prefer-stable": false, 1173 | "prefer-lowest": false, 1174 | "platform": [], 1175 | "platform-dev": [] 1176 | } 1177 | --------------------------------------------------------------------------------