├── .gitignore ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md └── src ├── assets.rs ├── cli.rs ├── main.rs └── metadata.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .DS_Store 3 | 4 | # Virtual environment 5 | venv 6 | 7 | # compiled Python 8 | *.pyc 9 | 10 | # pinboard credentials file 11 | pinboard-credentials 12 | 13 | # swap files 14 | *.swp 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | # v1.0.0 -- 2018-06-27 4 | 5 | Initial release! 6 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "backup-pinboard" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "hyper 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 8 | "reqwest 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", 11 | "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 12 | ] 13 | 14 | [[package]] 15 | name = "adler32" 16 | version = "1.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | 19 | [[package]] 20 | name = "advapi32-sys" 21 | version = "0.2.0" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | dependencies = [ 24 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 25 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 26 | ] 27 | 28 | [[package]] 29 | name = "aho-corasick" 30 | version = "0.6.3" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | dependencies = [ 33 | "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 34 | ] 35 | 36 | [[package]] 37 | name = "base64" 38 | version = "0.6.0" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | dependencies = [ 41 | "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 42 | "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 43 | ] 44 | 45 | [[package]] 46 | name = "bitflags" 47 | version = "0.9.1" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | 50 | [[package]] 51 | name = "byteorder" 52 | version = "1.1.0" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | 55 | [[package]] 56 | name = "bytes" 57 | version = "0.4.4" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | dependencies = [ 60 | "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 61 | "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 62 | ] 63 | 64 | [[package]] 65 | name = "cfg-if" 66 | version = "0.1.2" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | 69 | [[package]] 70 | name = "core-foundation" 71 | version = "0.2.3" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | dependencies = [ 74 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 75 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 76 | ] 77 | 78 | [[package]] 79 | name = "core-foundation-sys" 80 | version = "0.2.3" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | dependencies = [ 83 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 84 | ] 85 | 86 | [[package]] 87 | name = "crypt32-sys" 88 | version = "0.2.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | dependencies = [ 91 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 92 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 93 | ] 94 | 95 | [[package]] 96 | name = "docopt" 97 | version = "0.8.1" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | dependencies = [ 100 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 101 | "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 102 | "serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", 103 | "serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", 104 | "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 105 | ] 106 | 107 | [[package]] 108 | name = "dtoa" 109 | version = "0.4.1" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | 112 | [[package]] 113 | name = "foreign-types" 114 | version = "0.2.0" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | 117 | [[package]] 118 | name = "futures" 119 | version = "0.1.14" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | 122 | [[package]] 123 | name = "futures-cpupool" 124 | version = "0.1.5" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | dependencies = [ 127 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 128 | "num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 129 | ] 130 | 131 | [[package]] 132 | name = "gcc" 133 | version = "0.3.51" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | 136 | [[package]] 137 | name = "httparse" 138 | version = "1.2.3" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | 141 | [[package]] 142 | name = "hyper" 143 | version = "0.11.1" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | dependencies = [ 146 | "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 147 | "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 148 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 149 | "futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 150 | "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 151 | "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 152 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 153 | "mime 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 154 | "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 155 | "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", 156 | "tokio-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 157 | "tokio-io 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 158 | "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 159 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 160 | "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 161 | ] 162 | 163 | [[package]] 164 | name = "hyper-tls" 165 | version = "0.1.2" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | dependencies = [ 168 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 169 | "hyper 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", 170 | "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 171 | "tokio-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 172 | "tokio-io 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 173 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 174 | "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 175 | ] 176 | 177 | [[package]] 178 | name = "idna" 179 | version = "0.1.4" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | dependencies = [ 182 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 183 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 184 | "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 185 | ] 186 | 187 | [[package]] 188 | name = "iovec" 189 | version = "0.1.0" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | dependencies = [ 192 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 193 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 194 | ] 195 | 196 | [[package]] 197 | name = "itoa" 198 | version = "0.3.1" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | 201 | [[package]] 202 | name = "kernel32-sys" 203 | version = "0.2.2" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | dependencies = [ 206 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 207 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 208 | ] 209 | 210 | [[package]] 211 | name = "language-tags" 212 | version = "0.2.2" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | 215 | [[package]] 216 | name = "lazy_static" 217 | version = "0.2.8" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | 220 | [[package]] 221 | name = "lazycell" 222 | version = "0.4.0" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | 225 | [[package]] 226 | name = "libc" 227 | version = "0.2.26" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | 230 | [[package]] 231 | name = "libflate" 232 | version = "0.1.10" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | dependencies = [ 235 | "adler32 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 236 | "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 237 | ] 238 | 239 | [[package]] 240 | name = "log" 241 | version = "0.3.8" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | 244 | [[package]] 245 | name = "matches" 246 | version = "0.1.6" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | 249 | [[package]] 250 | name = "memchr" 251 | version = "1.0.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | dependencies = [ 254 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 255 | ] 256 | 257 | [[package]] 258 | name = "mime" 259 | version = "0.3.2" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | dependencies = [ 262 | "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 263 | ] 264 | 265 | [[package]] 266 | name = "mio" 267 | version = "0.6.9" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | dependencies = [ 270 | "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 271 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 272 | "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 273 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 274 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 275 | "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 276 | "net2 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", 277 | "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 278 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 279 | ] 280 | 281 | [[package]] 282 | name = "miow" 283 | version = "0.2.1" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | dependencies = [ 286 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 287 | "net2 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", 288 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 289 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 290 | ] 291 | 292 | [[package]] 293 | name = "native-tls" 294 | version = "0.1.4" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | dependencies = [ 297 | "openssl 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", 298 | "schannel 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 299 | "security-framework 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 300 | "security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 301 | "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 302 | ] 303 | 304 | [[package]] 305 | name = "net2" 306 | version = "0.2.30" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | dependencies = [ 309 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 310 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 311 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 312 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 313 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 314 | ] 315 | 316 | [[package]] 317 | name = "num-traits" 318 | version = "0.1.40" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | 321 | [[package]] 322 | name = "num_cpus" 323 | version = "1.6.2" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | dependencies = [ 326 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 327 | ] 328 | 329 | [[package]] 330 | name = "openssl" 331 | version = "0.9.15" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | dependencies = [ 334 | "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 335 | "foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 336 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 337 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 338 | "openssl-sys 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", 339 | ] 340 | 341 | [[package]] 342 | name = "openssl-sys" 343 | version = "0.9.15" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | dependencies = [ 346 | "gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)", 347 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 348 | "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 349 | ] 350 | 351 | [[package]] 352 | name = "percent-encoding" 353 | version = "1.0.0" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | 356 | [[package]] 357 | name = "pkg-config" 358 | version = "0.3.9" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | 361 | [[package]] 362 | name = "quote" 363 | version = "0.3.15" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | 366 | [[package]] 367 | name = "rand" 368 | version = "0.3.15" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | dependencies = [ 371 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 372 | ] 373 | 374 | [[package]] 375 | name = "redox_syscall" 376 | version = "0.1.26" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | 379 | [[package]] 380 | name = "regex" 381 | version = "0.2.2" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | dependencies = [ 384 | "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 385 | "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 386 | "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 387 | "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 388 | "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 389 | ] 390 | 391 | [[package]] 392 | name = "regex-syntax" 393 | version = "0.4.1" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | 396 | [[package]] 397 | name = "reqwest" 398 | version = "0.7.1" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | dependencies = [ 401 | "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 402 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 403 | "hyper 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", 404 | "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 405 | "libflate 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 406 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 407 | "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 408 | "serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", 409 | "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 410 | "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 411 | "tokio-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 412 | "tokio-io 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 413 | "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 414 | "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 415 | ] 416 | 417 | [[package]] 418 | name = "rustc_version" 419 | version = "0.1.7" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | dependencies = [ 422 | "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", 423 | ] 424 | 425 | [[package]] 426 | name = "safemem" 427 | version = "0.2.0" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | 430 | [[package]] 431 | name = "schannel" 432 | version = "0.1.7" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | dependencies = [ 435 | "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 436 | "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 437 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 438 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 439 | "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 440 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 441 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 442 | ] 443 | 444 | [[package]] 445 | name = "scoped-tls" 446 | version = "0.1.0" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | 449 | [[package]] 450 | name = "secur32-sys" 451 | version = "0.2.0" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | dependencies = [ 454 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 455 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 456 | ] 457 | 458 | [[package]] 459 | name = "security-framework" 460 | version = "0.1.14" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | dependencies = [ 463 | "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 464 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 465 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 466 | "security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 467 | ] 468 | 469 | [[package]] 470 | name = "security-framework-sys" 471 | version = "0.1.14" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | dependencies = [ 474 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 475 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 476 | ] 477 | 478 | [[package]] 479 | name = "semver" 480 | version = "0.1.20" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | 483 | [[package]] 484 | name = "serde" 485 | version = "1.0.10" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | 488 | [[package]] 489 | name = "serde_derive" 490 | version = "1.0.10" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | dependencies = [ 493 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 494 | "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", 495 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 496 | ] 497 | 498 | [[package]] 499 | name = "serde_derive_internals" 500 | version = "0.15.1" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | dependencies = [ 503 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 504 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 505 | ] 506 | 507 | [[package]] 508 | name = "serde_json" 509 | version = "1.0.2" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | dependencies = [ 512 | "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 513 | "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 514 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 515 | "serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", 516 | ] 517 | 518 | [[package]] 519 | name = "serde_urlencoded" 520 | version = "0.5.1" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | dependencies = [ 523 | "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 524 | "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 525 | "serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", 526 | "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 527 | ] 528 | 529 | [[package]] 530 | name = "slab" 531 | version = "0.3.0" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | 534 | [[package]] 535 | name = "smallvec" 536 | version = "0.2.1" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | 539 | [[package]] 540 | name = "strsim" 541 | version = "0.6.0" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | 544 | [[package]] 545 | name = "syn" 546 | version = "0.11.11" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | dependencies = [ 549 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 550 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 551 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 552 | ] 553 | 554 | [[package]] 555 | name = "synom" 556 | version = "0.11.3" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | dependencies = [ 559 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 560 | ] 561 | 562 | [[package]] 563 | name = "take" 564 | version = "0.1.0" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | 567 | [[package]] 568 | name = "tempdir" 569 | version = "0.3.5" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | dependencies = [ 572 | "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 573 | ] 574 | 575 | [[package]] 576 | name = "thread_local" 577 | version = "0.3.4" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | dependencies = [ 580 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 581 | "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 582 | ] 583 | 584 | [[package]] 585 | name = "time" 586 | version = "0.1.38" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | dependencies = [ 589 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 590 | "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", 591 | "redox_syscall 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", 592 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 593 | ] 594 | 595 | [[package]] 596 | name = "tokio-core" 597 | version = "0.1.8" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | dependencies = [ 600 | "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 601 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 602 | "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 603 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 604 | "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", 605 | "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 606 | "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 607 | "tokio-io 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 608 | ] 609 | 610 | [[package]] 611 | name = "tokio-io" 612 | version = "0.1.2" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | dependencies = [ 615 | "bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 616 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 617 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 618 | ] 619 | 620 | [[package]] 621 | name = "tokio-proto" 622 | version = "0.1.1" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | dependencies = [ 625 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 626 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 627 | "net2 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", 628 | "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 629 | "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 630 | "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 631 | "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 632 | "tokio-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 633 | "tokio-io 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 634 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 635 | ] 636 | 637 | [[package]] 638 | name = "tokio-service" 639 | version = "0.1.0" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | dependencies = [ 642 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 643 | ] 644 | 645 | [[package]] 646 | name = "tokio-tls" 647 | version = "0.1.3" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | dependencies = [ 650 | "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 651 | "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 652 | "tokio-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 653 | "tokio-io 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 654 | ] 655 | 656 | [[package]] 657 | name = "unicase" 658 | version = "2.0.0" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | dependencies = [ 661 | "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 662 | ] 663 | 664 | [[package]] 665 | name = "unicode-bidi" 666 | version = "0.3.4" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | dependencies = [ 669 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 670 | ] 671 | 672 | [[package]] 673 | name = "unicode-normalization" 674 | version = "0.1.5" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | 677 | [[package]] 678 | name = "unicode-xid" 679 | version = "0.0.4" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | 682 | [[package]] 683 | name = "unreachable" 684 | version = "1.0.0" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | dependencies = [ 687 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 688 | ] 689 | 690 | [[package]] 691 | name = "url" 692 | version = "1.5.1" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | dependencies = [ 695 | "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 696 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 697 | "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 698 | ] 699 | 700 | [[package]] 701 | name = "utf8-ranges" 702 | version = "1.0.0" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | 705 | [[package]] 706 | name = "void" 707 | version = "1.0.2" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | 710 | [[package]] 711 | name = "winapi" 712 | version = "0.2.8" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | 715 | [[package]] 716 | name = "winapi-build" 717 | version = "0.1.1" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | 720 | [[package]] 721 | name = "ws2_32-sys" 722 | version = "0.2.1" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | dependencies = [ 725 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 726 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 727 | ] 728 | 729 | [metadata] 730 | "checksum adler32 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ff33fe13a08dbce05bcefa2c68eea4844941437e33d6f808240b54d7157b9cd" 731 | "checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" 732 | "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" 733 | "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" 734 | "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" 735 | "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" 736 | "checksum bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8b24f16593f445422331a5eed46b72f7f171f910fead4f2ea8f17e727e9c5c14" 737 | "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" 738 | "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" 739 | "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" 740 | "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" 741 | "checksum docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b5b93718f8b3e5544fcc914c43de828ca6c6ace23e0332c6080a2977b49787a" 742 | "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" 743 | "checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" 744 | "checksum futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4b63a4792d4f8f686defe3b39b92127fea6344de5d38202b2ee5a11bbbf29d6a" 745 | "checksum futures-cpupool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a283c84501e92cade5ea673a2a7ca44f71f209ccdd302a3e0896f50083d2c5ff" 746 | "checksum gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "120d07f202dcc3f72859422563522b66fe6463a4c513df062874daad05f85f0a" 747 | "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" 748 | "checksum hyper 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75f57d451deabf8ad8fa1488d27b24834c9f5b6ca996da8d0c9dc5ce9c8d4d34" 749 | "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" 750 | "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" 751 | "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be" 752 | "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" 753 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 754 | "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" 755 | "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" 756 | "checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b" 757 | "checksum libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "30885bcb161cf67054244d10d4a7f4835ffd58773bc72e07d35fecf472295503" 758 | "checksum libflate 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "bb9e5c68bd981985afa70d22a81f339bb0ea8a071760e99894d6d393417e4a29" 759 | "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" 760 | "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" 761 | "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" 762 | "checksum mime 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c5ca99d8a021c1687882fd68dca26e601ceff5c26571c7cb41cf4ed60d57cb2d" 763 | "checksum mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9e965267d4d58496fc4f740e9861118367f13570cadf66316ed2c3f2f14d87c7" 764 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 765 | "checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5" 766 | "checksum net2 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)" = "94101fd932816f97eb9a5116f6c1a11511a1fed7db21c5ccd823b2dc11abf566" 767 | "checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" 768 | "checksum num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aec53c34f2d0247c5ca5d32cca1478762f301740468ee9ee6dcb7a0dd7a0c584" 769 | "checksum openssl 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f776f1d8af832fd2c637ee182c801e8f7ea8895718a2be9914cca001f6e2c40a" 770 | "checksum openssl-sys 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "ad95f8160d1c150c4f44d4c4959732e048ac046c37f597fe362f8bf57561ffb4" 771 | "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" 772 | "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" 773 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 774 | "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" 775 | "checksum redox_syscall 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "9df6a71a1e67be2104410736b2389fb8e383c1d7e9e792d629ff13c02867147a" 776 | "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" 777 | "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" 778 | "checksum reqwest 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5ccc5505e66049646295469087f08f65915faec98eeb4e3a4d4d444b4cdd0d5" 779 | "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" 780 | "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" 781 | "checksum schannel 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "14a5f8491ae5fc8c51aded1f5806282a0218b4d69b1b76913a0559507e559b90" 782 | "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" 783 | "checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" 784 | "checksum security-framework 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "42ddf098d78d0b64564b23ee6345d07573e7d10e52ad86875d89ddf5f8378a02" 785 | "checksum security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "5bacdada57ea62022500c457c8571c17dfb5e6240b7c8eac5916ffa8c7138a55" 786 | "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" 787 | "checksum serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "433d7d9f8530d5a939ad5e0e72a6243d2e42a24804f70bf592c679363dcacb2f" 788 | "checksum serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7b707cf0d4cab852084f573058def08879bb467fda89d99052485e7d00edd624" 789 | "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" 790 | "checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" 791 | "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" 792 | "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" 793 | "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" 794 | "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" 795 | "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 796 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 797 | "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" 798 | "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" 799 | "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" 800 | "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" 801 | "checksum tokio-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6a20ba4738d283cac7495ca36e045c80c2a8df3e05dd0909b17a06646af5a7ed" 802 | "checksum tokio-io 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c2c3ce9739f7387a0fa65b5421e81feae92e04d603f008898f4257790ce8c2db" 803 | "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" 804 | "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" 805 | "checksum tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d88e411cac1c87e405e4090be004493c5d8072a370661033b1a64ea205ec2e13" 806 | "checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80" 807 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 808 | "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" 809 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 810 | "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 811 | "checksum url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27" 812 | "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" 813 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 814 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 815 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 816 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 817 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "backup-pinboard" 3 | version = "1.0.0" 4 | authors = ["Alex Chan "] 5 | 6 | [dependencies] 7 | docopt = "0.8.1" 8 | hyper = "0.11.1" 9 | regex = "0.2.2" 10 | reqwest = "0.7.1" 11 | serde = "1.0.10" 12 | serde_derive = "1.0" 13 | url = "1.5.1" 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Alex Chan 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # backup-pinboard 2 | 3 | This is a tool for creating a local backup of your Pinboard bookmarks. 4 | 5 | ## Installation 6 | 7 | Building this project [requires Rust][rust] (1.19 or later). 8 | Then install the project using Cargo: 9 | 10 | ```console 11 | $ cargo install --git https://github.com/alexwlchan/backup-pinboard.git 12 | ``` 13 | 14 | You need to add `~/.cargo/bin` to your PATH. 15 | 16 | [rust]: https://www.rust-lang.org/en-US/ 17 | 18 | ## Usage 19 | 20 | Download your bookmarks metadata: 21 | 22 | ```console 23 | $ backup-pinboard metadata --username=USERNAME --password=PASSWORD 24 | ``` 25 | 26 | This downloads your metadata to `bookmarks.json`. 27 | You can specify an alternative path with `--outfile`, for example: 28 | 29 | ```console 30 | $ backup-pinboard metadata --username=USERNAME --password=PASSWORD --outfile=~/backups/pinboard.json 31 | ``` 32 | 33 | If the outfile name ends in `.xml`, metadata is saved as XML instead of JSON. 34 | 35 | If you have an archival account, you can also download copies of your saved pages: 36 | 37 | ```console 38 | $ backup-pinboard archive --username=USERNAME --password=PASSWORD --outdir=~/backups/pinboard-archive 39 | ``` 40 | 41 | ## The old Python script 42 | 43 | This used to be a Python script; in July 2017 I completely rewrote the tool in Rust. 44 | You can browse the repo [at commit 6dcc06e][python] for the last version of the Python scripts. 45 | 46 | [python]: https://github.com/alexwlchan/backup-pinboard/tree/6dcc06e49a4863803d5a2a0c9ac23bfec2f4bcf3 47 | 48 | ## License 49 | 50 | MIT. 51 | -------------------------------------------------------------------------------- /src/assets.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::io::Read; 3 | use std::process; 4 | 5 | use hyper::header::Header; 6 | use regex::Regex; 7 | use reqwest::header::{Cookie, Location, SetCookie}; 8 | use reqwest::{Client, RedirectPolicy}; 9 | 10 | 11 | /// Log in to Pinboard and get a login cookie that can be used on subsequent 12 | /// requests. 13 | /// 14 | fn get_login_cookie(username: &str, password: &str) -> Cookie { 15 | // Start by logging in to Pinboard, so we have the appropriate cookies. 16 | // Because Pinboard sends us into a weird redirect loop, we have to 17 | // tell reqwest not to follow redirects, just check the redirect worked. 18 | let client = Client::builder() 19 | .unwrap() 20 | .redirect(RedirectPolicy::none()) 21 | .build() 22 | .unwrap(); 23 | 24 | let resp = client.post("https://pinboard.in/auth/") 25 | .unwrap() 26 | .form(&[("username", &username), ("password", &password)]) 27 | .unwrap() 28 | .send(); 29 | let headers = resp.ok().unwrap().headers().to_owned(); 30 | let login_successful = headers 31 | .get::() 32 | .unwrap() != &Location::new("?error=wrong+password"); 33 | if !login_successful { 34 | eprintln!("Error logging in to Pinboard!"); 35 | process::exit(1); 36 | } 37 | 38 | // Cookie-handling code. This should probably be handled by reqwest, 39 | // but I've given up trying to get it working, and I'm just doing it 40 | // by hand instead. Pinboard only sets four interesting cookie values. 41 | let set_cookie = headers 42 | .get::() 43 | .unwrap(); 44 | let mut cookie = Cookie::new(); 45 | for c in set_cookie.iter() { 46 | let parsed = Cookie::parse_header(&c.as_bytes().into()).unwrap(); 47 | for key in vec!["groznaz", "auth", "secauth", "login"].iter() { 48 | match parsed.get(key) { 49 | Some(val) => cookie.set(key.to_owned(), val.to_owned()), 50 | None => {}, 51 | }; 52 | } 53 | } 54 | 55 | cookie 56 | } 57 | 58 | 59 | /// Given a blob of HTML from a Pinboard index, update the map of cache IDs 60 | /// and corresponding links. 61 | fn get_cache_ids_from_html(html: &str, cache_ids: &mut HashMap) { 62 | // Parsing HTML with regex or string manipulation is, in general, 63 | // a terrible idea. I'm doing it here because I couldn't work out how 64 | // to use html5ever from their API docs, and I'm tired. 65 | // TODO: Write this to be not terrible. 66 | 67 | // All the bookmarks on a page are in a 68 | // 69 | //
70 | // 71 | // block, so start by extracting that. 72 | let bookmarks_div = html 73 | .split("
").collect::>()[1] 74 | .split("
").collect::>()[0]; 75 | 76 | // Individual bookmarks always have 77 | // 78 | //
79 | // 80 | // at the top, so we can use this as a rough proxy for bookmarks. 81 | let mut bookmarks = bookmarks_div 82 | .split("
"); 83 | 84 | // Discard the first entry. 85 | bookmarks.next(); 86 | 87 | // The links to cached bookmarks are of the form 88 | // 89 | // 90 | // 91 | let cached_re = Regex::new( 92 | "[0-9a-f]+)/\">" 93 | ).unwrap(); 94 | 95 | // The links to bookmarks are of the form 96 | // 97 | // [^\"]+)\"" 101 | ).unwrap(); 102 | 103 | for b in bookmarks { 104 | if cached_re.is_match(b) { 105 | let cache_match = cached_re.captures(b) 106 | .unwrap()["cache_id"] 107 | .to_owned(); 108 | 109 | let link_match = link_re.captures(b) 110 | .unwrap()["link_href"] 111 | .to_owned(); 112 | 113 | cache_ids.insert(link_match, cache_match); 114 | } else { 115 | // This doesn't have a link, so we can't save it. 116 | continue; 117 | } 118 | } 119 | } 120 | 121 | 122 | fn get_html_for_page(client: &Client, path: &str, cookie: &Cookie) -> String { 123 | let url = format!("https://pinboard.in{}", path); 124 | let resp = client.get(&url) 125 | .unwrap() 126 | .header(cookie.to_owned()) 127 | .send(); 128 | let mut content = String::new(); 129 | let _ = resp.ok().unwrap().read_to_string(&mut content); 130 | content 131 | } 132 | 133 | 134 | fn get_next_page_path(html: &str) -> Option { 135 | let next_href_re = Regex::new( 136 | "[^\"]+)\">« earlier" 137 | ).unwrap(); 138 | 139 | match next_href_re.captures(html) { 140 | Some(s) => Some(s["next_href"].to_owned()), 141 | None => None, 142 | } 143 | } 144 | 145 | 146 | fn update_cache_ids_for_path(client: &Client, path: &str, cookie: &Cookie, mut cache_ids: &mut HashMap) { 147 | println!("Inspecting path {}", path); 148 | let content = get_html_for_page(&client, &path, &cookie); 149 | get_cache_ids_from_html(&content, &mut cache_ids); 150 | match get_next_page_path(&content) { 151 | Some(next_path) => update_cache_ids_for_path(&client, &next_path, &cookie, &mut cache_ids), 152 | None => {} 153 | }; 154 | } 155 | 156 | 157 | /// Return a map from URLs to Pinboard cache IDs. 158 | /// 159 | /// - `username`: Pinboard username 160 | /// - `password`: Pinboard password 161 | /// 162 | pub fn get_cache_ids(username: &str, password: &str) -> HashMap { 163 | 164 | let client = Client::new().unwrap(); 165 | let cookie = get_login_cookie(&username, &password); 166 | let mut cache_ids = HashMap::new(); 167 | 168 | // Now fetch a blob of HTML for the first page. 169 | let path = format!("/u:{}/", username); 170 | update_cache_ids_for_path(&client, &path, &cookie, &mut cache_ids); 171 | 172 | cache_ids 173 | } 174 | -------------------------------------------------------------------------------- /src/cli.rs: -------------------------------------------------------------------------------- 1 | use docopt::Docopt; 2 | 3 | const USAGE: &str = " 4 | Usage: metadata --username= --password= [--outfile=] 5 | archive --username= --password= [--outdir=] 6 | (-h | --help) 7 | --version 8 | 9 | Options: 10 | -h --help Show this screen. 11 | --version Show version. 12 | --username= Pinboard username. 13 | --password= Pinboard password. 14 | --outfile= Write your bookmark metadata to OUTFILE. 15 | --outdir= Save your archived bookmarks in OUTDIR. 16 | 17 | Commands: 18 | metadata Save a file containing metadata about all your 19 | bookmarks. 20 | archive Download a copy of the bookmarks saved by the 21 | Pinboard archiver (https://pinboard.in/upgrade/). 22 | Requires GNU wget. 23 | "; 24 | 25 | #[derive(Debug, Deserialize)] 26 | pub struct Args { 27 | pub cmd_metadata: bool, 28 | pub cmd_archive: bool, 29 | pub flag_version: bool, 30 | pub flag_username: Option, 31 | pub flag_password: Option, 32 | pub flag_outfile: Option, 33 | pub flag_outdir: Option, 34 | } 35 | 36 | pub fn parse_args(name: &str) -> Args { 37 | Docopt::new(str::replace(USAGE, "", name)) 38 | .and_then(|d| d.deserialize()) 39 | .unwrap_or_else(|e| e.exit()) 40 | } 41 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::Write; 3 | use std::path::Path; 4 | use std::process; 5 | 6 | extern crate docopt; 7 | extern crate hyper; 8 | extern crate regex; 9 | extern crate reqwest; 10 | #[macro_use] 11 | extern crate serde_derive; 12 | 13 | mod assets; 14 | mod cli; 15 | mod metadata; 16 | 17 | const NAME: &str = env!("CARGO_PKG_NAME"); 18 | const VERSION: &str = env!("CARGO_PKG_VERSION"); 19 | 20 | 21 | fn create_wget_login_cookie(username: &str, password: &str) { 22 | process::Command::new("wget") 23 | .args(&["--save-cookies", "/tmp/pinboard-cookies.txt"]) 24 | .arg("--keep-session-cookies") 25 | .arg("--delete-after") 26 | .args(&["--output-file", "-"]) 27 | .args(&["--post-data", &format!("username={}&password={}", username, password)]) 28 | .arg("https://pinboard.in/auth/") 29 | .output() 30 | .expect("Failed to authenticate against Pinboard with wget"); 31 | } 32 | 33 | fn main() { 34 | let args = cli::parse_args(NAME); 35 | 36 | if args.flag_version { 37 | println!("{} v{}", NAME, VERSION); 38 | } 39 | 40 | else if args.cmd_metadata { 41 | let username = args.flag_username.unwrap(); 42 | let password = args.flag_password.unwrap(); 43 | let outfile = args.flag_outfile.unwrap_or("bookmarks.json".to_owned()); 44 | let format = metadata::guess_format(&outfile); 45 | 46 | let data = metadata::get_metadata(username, password, format); 47 | 48 | let mut buffer = File::create(&outfile).unwrap(); 49 | let _ = buffer.write(data.as_bytes()); 50 | } 51 | 52 | else if args.cmd_archive { 53 | let username = args.flag_username.unwrap(); 54 | let password = args.flag_password.unwrap(); 55 | let out_dir = args.flag_outdir.unwrap_or("archive".to_owned()); 56 | 57 | let cache_ids = assets::get_cache_ids(&username, &password); 58 | println!("{:?}", cache_ids); 59 | 60 | create_wget_login_cookie(&username, &password); 61 | 62 | for cache_id in cache_ids.values() { 63 | println!("Fetching cache for {}", cache_id); 64 | let url = format!("https://pinboard.in/cached/{}/", cache_id); 65 | let local_out_dir = format!("{}/{}", out_dir, cache_id); 66 | let path = Path::new(&local_out_dir); 67 | if path.exists() { 68 | println!("Cache for {} already exists, skipping", cache_id); 69 | continue; 70 | } 71 | process::Command::new("wget") 72 | .arg("--adjust-extension") 73 | .arg("--span-hosts") 74 | .arg("--no-verbose") 75 | .arg("--convert-links") 76 | .arg("--page-requisites") 77 | .arg("--no-directories") 78 | .args(&["-e", "robots=off"]) 79 | .args(&["--load-cookies", "/tmp/pinboard-cookies.txt"]) 80 | .args(&["--output-file", "-"]) 81 | .args(&["--directory-prefix", &local_out_dir]) 82 | .arg(&url) 83 | .output() 84 | .expect("Failed to download archive from Pinboard"); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/metadata.rs: -------------------------------------------------------------------------------- 1 | use std::io::Read; 2 | use std::process; 3 | 4 | use reqwest; 5 | 6 | 7 | /// Represents the different formats returned 8 | pub enum Format { 9 | JSON, 10 | XML, 11 | } 12 | 13 | 14 | pub fn guess_format(outfile_name: &str) -> Format { 15 | if outfile_name.to_lowercase().ends_with(".xml") { 16 | Format::XML 17 | } else { 18 | Format::JSON 19 | } 20 | } 21 | 22 | 23 | /// Return metadata about all your posts from the Pinboard API. 24 | /// 25 | /// - `username`: Pinboard username 26 | /// - `password`: Pinboard password 27 | /// 28 | pub fn get_metadata(username: String, password: String, format: Format) -> String { 29 | 30 | let url = match format { 31 | Format::XML => "https://api.pinboard.in/v1/posts/all", 32 | Format::JSON => "https://api.pinboard.in/v1/posts/all?format=json", 33 | }; 34 | 35 | let client = reqwest::Client::new().unwrap(); 36 | let resp = client.get(url) 37 | .unwrap() 38 | .basic_auth(username, Some(password)) 39 | .send(); 40 | let mut content = String::new(); 41 | 42 | match resp { 43 | Ok(mut r) => { 44 | if r.status().is_success() { 45 | let _ = r.read_to_string(&mut content); 46 | } else { 47 | eprint!("Error status code from the Pinboard API: {}", r.status()); 48 | process::exit(1); 49 | } 50 | } 51 | Err(e) => { 52 | eprint!("Unexpected error calling the Pinboard API: {}", e); 53 | process::exit(2); 54 | } 55 | } 56 | 57 | content 58 | } 59 | --------------------------------------------------------------------------------