Merge branch 'client-rework' into 'master'

Client rework

See merge request alatiera/Hammond!3
This commit is contained in:
Jordan Petridis 2017-12-09 04:25:39 +00:00
commit 8b4684679b
33 changed files with 1149 additions and 863 deletions

View File

@ -14,53 +14,34 @@ before_script:
# kcov
# - apt-get install -y libcurl4-openssl-dev libelf-dev libdw-dev cmake gcc binutils-dev libiberty-dev
.cargo_test_template: &cargo_test
stage: test
script:
- rustc --version && cargo --version
- cargo build
- cargo test --verbose -- --test-threads=1
variables:
# RUSTFLAGS: "-C link-dead-code"
RUST_BACKTRACE: "FULL"
# Currently doesnt work.
# # Build with meson
# build:stable:
# # Stable img
# # https://hub.docker.com/_/rust/
# image: "rust"
# script:
# - rustc --version && cargo --version
# - ./configure --prefix=/usr/local
# - make && sudo make install
# build:nightly:
# # Nightly
# # https://hub.docker.com/r/rustlang/rust/
# image: "rustlang/rust:nightly"
# script:
# - rustc --version && cargo --version
# - ./configure --prefix=/usr/local
# - make && sudo make install
test:stable:
# Stable img
stable:test:
# https://hub.docker.com/_/rust/
image: "rust"
script:
- rustc --version && cargo --version
- cargo build
- cargo test --verbose -- --test-threads=1
<<: *cargo_test
test:nightly:
# Nightly
nightly:test:
# https://hub.docker.com/r/rustlang/rust/
image: "rustlang/rust:nightly"
script:
- rustc --version && cargo --version
- cargo build
- cargo test --verbose -- --test-threads=1
# - cargo bench
<<: *cargo_test
# Configure and run rustfmt on nightly
# Exits and builds fails if on bad format
lint:rustfmt:
rustfmt:
image: "rustlang/rust:nightly"
stage: lint
variables:
CFG_RELEASE_CHANNEL: "nightly"
script:
- rustc --version && cargo --version
- cargo install rustfmt-nightly
@ -68,8 +49,9 @@ lint:rustfmt:
# Configure and run clippy on nightly
# Only fails on errors atm.
lint:clippy:
clippy:
image: "rustlang/rust:nightly"
stage: lint
script:
- rustc --version && cargo --version
- cargo install clippy

324
Cargo.lock generated
View File

@ -14,10 +14,23 @@ dependencies = [
[[package]]
name = "aho-corasick"
version = "0.6.3"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ammonia"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"html5ever 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"maplit 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -38,7 +51,7 @@ dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -48,7 +61,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -62,7 +75,7 @@ dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -73,7 +86,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -81,7 +94,7 @@ name = "base64"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -107,7 +120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.1.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -115,7 +128,7 @@ name = "bytes"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -133,7 +146,7 @@ dependencies = [
"cairo-sys-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -142,7 +155,7 @@ name = "cairo-sys-rs"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -162,7 +175,7 @@ name = "chrono"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -181,7 +194,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -189,7 +202,7 @@ name = "core-foundation-sys"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -256,31 +269,30 @@ dependencies = [
[[package]]
name = "diesel"
version = "0.16.0"
source = "git+https://github.com/diesel-rs/diesel.git#07f80c3a0d07daa26efff3166fbf0297dc0f0a7b"
version = "0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_derives 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "diesel_codegen"
version = "0.16.0"
source = "git+https://github.com/diesel-rs/diesel.git#07f80c3a0d07daa26efff3166fbf0297dc0f0a7b"
name = "diesel_derives"
version = "0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"diesel 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"diesel_infer_schema 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "diesel_infer_schema"
version = "0.16.0"
source = "git+https://github.com/diesel-rs/diesel.git#07f80c3a0d07daa26efff3166fbf0297dc0f0a7b"
name = "diesel_migrations"
version = "0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"diesel 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"migrations_internals 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"migrations_macros 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -299,7 +311,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -338,7 +350,15 @@ dependencies = [
[[package]]
name = "foreign-types"
version = "0.2.0"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -394,7 +414,7 @@ dependencies = [
"glib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pango 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -407,7 +427,7 @@ dependencies = [
"glib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -419,7 +439,7 @@ dependencies = [
"gio-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -434,7 +454,7 @@ dependencies = [
"gio-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -449,7 +469,7 @@ dependencies = [
"glib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -460,7 +480,7 @@ dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -473,7 +493,7 @@ dependencies = [
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -482,7 +502,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -493,7 +513,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -515,7 +535,7 @@ dependencies = [
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gtk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pango 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -532,7 +552,7 @@ dependencies = [
"gio-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -541,20 +561,22 @@ dependencies = [
name = "hammond-data"
version = "0.1.0"
dependencies = [
"ammonia 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"diesel_codegen 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_migrations 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2-diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2-diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rfc822_sanitizer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rss 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rss 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -564,12 +586,12 @@ dependencies = [
name = "hammond-downloader"
version = "0.1.0"
dependencies = [
"diesel 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hammond-data 0.1.0",
"hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 1.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -578,8 +600,7 @@ dependencies = [
name = "hammond-gtk"
version = "0.1.0"
dependencies = [
"diesel 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"diesel_codegen 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dissolve 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-pixbuf 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -589,9 +610,10 @@ dependencies = [
"hammond-data 0.1.0",
"hammond-downloader 0.1.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"loggerv 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -663,7 +685,7 @@ name = "iovec"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -691,6 +713,11 @@ name = "lazy_static"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazycell"
version = "0.5.1"
@ -698,7 +725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.33"
version = "0.2.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -707,7 +734,7 @@ version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -727,7 +754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "loggerv"
version = "0.5.1"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -740,6 +767,11 @@ name = "mac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "maplit"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "markup5ever"
version = "0.6.2"
@ -760,10 +792,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "1.0.2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "migrations_internals"
version = "0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "migrations_macros"
version = "0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"migrations_internals 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -784,7 +834,7 @@ dependencies = [
[[package]]
name = "mime_guess"
version = "1.8.2"
version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -795,7 +845,7 @@ dependencies = [
[[package]]
name = "mime_guess"
version = "2.0.0-alpha.2"
version = "2.0.0-alpha.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -814,7 +864,7 @@ dependencies = [
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
@ -838,7 +888,7 @@ name = "native-tls"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"openssl 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -852,19 +902,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num"
version = "0.1.40"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -872,7 +922,7 @@ name = "num-integer"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -881,12 +931,12 @@ version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.1.40"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -894,7 +944,7 @@ name = "num_cpus"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -904,23 +954,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "openssl"
version = "0.9.21"
version = "0.9.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys"
version = "0.9.21"
version = "0.9.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -934,7 +984,7 @@ dependencies = [
"glib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -946,7 +996,7 @@ dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1002,12 +1052,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quick-xml"
version = "0.9.4"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1017,21 +1067,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "r2d2"
version = "0.7.4"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"scheduled-thread-pool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r2d2-diesel"
version = "0.16.0"
version = "0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"diesel 0.16.0 (git+https://github.com/diesel-rs/diesel.git)",
"r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1040,7 +1090,7 @@ version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1059,14 +1109,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.31"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -1074,16 +1124,16 @@ name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1113,10 +1163,10 @@ dependencies = [
"hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1132,16 +1182,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rss"
version = "1.1.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-xml 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-xml 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1175,7 +1225,7 @@ dependencies = [
[[package]]
name = "scheduled-thread-pool"
version = "0.1.0"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1207,7 +1257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1217,23 +1267,23 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "1.0.21"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_json"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1243,7 +1293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1276,7 +1326,7 @@ dependencies = [
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1343,8 +1393,8 @@ name = "termion"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1363,8 +1413,8 @@ version = "0.1.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1552,7 +1602,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a"
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
"checksum ammonia 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc0ea12b4977283c563e78eaf227b024d89d72a6394040fad4063899bfcfb48"
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
"checksum atk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33a67fd81e1922dddc335887516f2f5254534e89c9d39fa89bca5d79bd150d34"
@ -1564,7 +1615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9"
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6"
"checksum c_vec 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6237ac5a4b1e81c213c24c6437964c61e646df910a914b4ab1487b46df20bd13"
"checksum cairo-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6b5695f59fd036fe5741bc5a4eb20c78fbe42256e3b08a2af26bbcbe8070bf3"
@ -1582,9 +1633,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a"
"checksum derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03600ae366b6eb2314e54d62adc833d9866da03798acc61c61789654ceaa227a"
"checksum derive_builder_core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eed37eae64daa5511467b1a55cebdf472deeaef108d22f62f25e8bbcaffd56ac"
"checksum diesel 0.16.0 (git+https://github.com/diesel-rs/diesel.git)" = "<none>"
"checksum diesel_codegen 0.16.0 (git+https://github.com/diesel-rs/diesel.git)" = "<none>"
"checksum diesel_infer_schema 0.16.0 (git+https://github.com/diesel-rs/diesel.git)" = "<none>"
"checksum diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b97bd43f72d4819fac99f24d0030184c64c5ebdee96f94c7a7d4215c50506a7"
"checksum diesel_derives 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad228b6fd05c86050b95f56e497a8135073ffce28602e2200e63a21047eb474d"
"checksum diesel_migrations 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "745dcfe39e3043c267e46dbe4f2ebbc9917039bdf4d81b108950be61244dfc89"
"checksum dissolve 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "898542be4716d992082c8e4fc331b792d626cfa71cb2b4790f828b9a8f921a90"
"checksum dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f0e2bb24d163428d8031d3ebd2d2bd903ad933205a97d0f18c7c1aade380f3"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
@ -1592,7 +1643,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
"checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3"
@ -1619,32 +1671,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b"
"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2"
"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
"checksum libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ae46bcdafa496981e996e57c5be82c0a7f130a071323764c6faa4803619f1e67"
"checksum libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "370090ad578ba845a3ad4f383ceb3deba7abd51ab1915ad1f2c982cc6035e31c"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum loggerv 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5bb7c9e1ed99294067005cc7d4413441197ba354e8286c36b72a66a557c13661"
"checksum loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b178879253fab6ddb4ea931e1e6f514d45ce6a53f7fe618a0a8751f43e42e4f1"
"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
"checksum maplit 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ed95049d40b8a1a7691adbabca028ad481f7e6a2921ce4846e1ee168b4e4ca5"
"checksum markup5ever 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2cf89d3e0486c32c9d99521455ddf9a438910a1ce2bd376936086edc15dff5fc"
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
"checksum migrations_internals 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ac1d17f6f161f4d91cb7e5a72cce5b24a60b80f96580a8ac94351c56b8606a"
"checksum migrations_macros 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc767420eac6b718cd593aaa09c06a31d4ed228291c8538b274737e28a29939b"
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
"checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd"
"checksum mime_guess 1.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bbee1a836f344ac39d4a59bfe7be2bd3150353ff71678afb740216f8270b333e"
"checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae"
"checksum mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7e82a15629bb4ecd9e72365bf33d1382be91e030f820edb8e2a21c02430da8"
"checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495"
"checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5"
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
"checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525"
"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca"
"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
"checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113"
"checksum openssl 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)" = "2225c305d8f57001a0d34263e046794aa251695f20773102fbbfeb1e7b189955"
"checksum openssl-sys 0.9.21 (registry+https://github.com/rust-lang/crates.io-index)" = "92867746af30eea7a89feade385f7f5366776f1c52ec6f0de81360373fa88363"
"checksum openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "419ef26bb651d72b6c5a603bcc4e4856a362460e62352dfffa53de91d2e81181"
"checksum openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5483bdc56756041ba6aa37c9cb59cc2219f012a2a1377d97ad35556ac6676ee7"
"checksum pango 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e81c404ab81ea7ea2fc2431a0a7672507b80e4b8bf4b41eac3fc83cc665104e"
"checksum pango-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34f34a1be107fe16abb2744e0e206bee4b3b07460b5fddd3009a6aaf60bd69ab"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
@ -1654,33 +1710,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum quick-xml 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "19a3a610544419c527d5f51ae1a6ae3db533e25c117d3eed8fce6434f70c5e95"
"checksum quick-xml 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d0fb3e41d968cd20da34a9e81abae097398b38fe0987149e321572eb75d3317"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2c8284508b38df440f8f3527395e23c4780b22f74226b270daf58fee38e4bcce"
"checksum r2d2-diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6b921696a6c45991296d21b52ed973b9fb56f6c47524fda1f99458c2d6c0478"
"checksum r2d2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "59611202bee496c586ecd84e3ed149b4ec75981b0fc10d7f60e878fa23ae16e9"
"checksum r2d2-diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77aaed149a82720f4b664427f359e1b2a34d8787c1bc3fb1d167b104a1ddd866"
"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
"checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf"
"checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53"
"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5"
"checksum reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f73a8482e3b2b20ef5c07168b27048fc3778a012ce9b11a021556a450a01e9b5"
"checksum rfc822_sanitizer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "680e8305c1e0cdf836dc4bec5424e045f278c975a3cac36d1ca01c4695f9d815"
"checksum rss 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70294b2be2d620fed3939032067684c53b8ccae18e8ca0b8410447f0f07228c5"
"checksum rss 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fbc1a0587ebbc7404b3295c8e1f717d00dad48e3c205adadf916f15ff67d05b"
"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
"checksum schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7554288337c1110e34d7a2433518d889374c1de1a45f856b7bcddb03702131fc"
"checksum scheduled-thread-pool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d9fbe48ead32343b76f544c85953bf260ed39219a8bbbb62cd85f6a00f9644f"
"checksum scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2ff3fc5223829be817806c6441279c676e454cc7da608faf03b0ccc09d3889"
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc"
"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332"
"checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead"
"checksum serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6eda663e865517ee783b0891a3f6eb3a253e0b0dabb46418969ee9635beadd9e"
"checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e"
"checksum serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c37d7f192f00041e8a613e936717923a71bc0c9051fc4425a49b104140f05"
"checksum serde_json 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ea28ea0cca944668919bec6af209864a8dfe769fd2b0b723f36b22e20c1bf69f"
"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480"
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"

View File

@ -8,7 +8,3 @@ members = [
[profile.release]
debug = false
[patch.crates-io]
diesel = { git = "https://github.com/diesel-rs/diesel.git" }
diesel_infer_schema = { git = "https://github.com/diesel-rs/diesel.git" }
diesel_codegen = { git = "https://github.com/diesel-rs/diesel.git" }

View File

@ -1,14 +1,9 @@
## TODOs:
**General:**
- [ ] Write docs
## Planned Features
## Priorities:
- [ ] Discuss and decide when to schedule the download cleaner. [#3](https://gitlab.gnome.org/alatiera/Hammond/issues/3)
- [ ] Unplayed Only and Downloaded only view.
- [ ] Auto-updater
- [ ] OPML import/export // Probably need to create a crate.

View File

@ -5,27 +5,29 @@ version = "0.1.0"
workspace = "../"
[dependencies]
ammonia = "1.0.0"
chrono = "0.4.0"
derive_builder = "0.5.0"
dotenv = "0.10.1"
error-chain = "0.11.0"
lazy_static = "0.2.11"
lazy_static = "1.0.0"
log = "0.3.8"
r2d2 = "0.7.4"
r2d2-diesel = "0.16.0"
r2d2 = "0.8.1"
r2d2-diesel = "0.99.0"
rayon = "0.9.0"
reqwest = "0.8.1"
rfc822_sanitizer = "0.3.3"
rss = "1.1.0"
rss = "1.2.1"
url = "1.6.0"
xdg = "2.1.0"
[dependencies.diesel]
features = ["sqlite"]
git = "https://github.com/diesel-rs/diesel.git"
version = "0.99.0"
[dependencies.diesel_codegen]
[dependencies.diesel_migrations]
features = ["sqlite"]
git = "https://github.com/diesel-rs/diesel.git"
version = "0.99.0"
[dev-dependencies]
rand = "0.3.18"

View File

@ -3,16 +3,14 @@ use diesel::prelude::*;
use r2d2;
use std::path::PathBuf;
use std::sync::Arc;
use std::io;
use std::time::Duration;
use errors::*;
#[cfg(not(test))]
use xdg_dirs;
type Pool = Arc<r2d2::Pool<ConnectionManager<SqliteConnection>>>;
type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
embed_migrations!("migrations/");
@ -38,19 +36,18 @@ lazy_static! {
}
pub(crate) fn connection() -> Pool {
Arc::clone(&POOL)
POOL.clone()
}
fn init_pool(db_path: &str) -> Pool {
let config = r2d2::Config::builder()
.pool_size(1)
.connection_timeout(Duration::from_secs(60))
.build();
let manager = ConnectionManager::<SqliteConnection>::new(db_path);
let pool = Arc::new(r2d2::Pool::new(config, manager).expect("Failed to create pool."));
let pool = r2d2::Pool::builder()
.max_size(1)
.build(manager)
.expect("Failed to create pool.");
{
let db = Arc::clone(&pool).get().expect("Failed to initialize pool.");
let db = pool.get().expect("Failed to initialize pool.");
run_migration_on(&*db).expect("Failed to run migrations during init.");
}
info!("Database pool initialized.");

View File

@ -198,9 +198,10 @@ pub fn update_none_to_played_now(parent: &Podcast) -> Result<usize> {
let epoch_now = Utc::now().timestamp() as i32;
con.transaction(|| -> Result<usize> {
Ok(diesel::update(
Episode::belonging_to(parent).filter(played.is_null()),
).set(played.eq(Some(epoch_now)))
.execute(&*con)?)
Ok(
diesel::update(Episode::belonging_to(parent).filter(played.is_null()))
.set(played.eq(Some(epoch_now)))
.execute(&*con)?,
)
})
}

View File

@ -1,5 +1,5 @@
use diesel::result;
use diesel::migrations::RunMigrationsError;
use diesel_migrations::RunMigrationsError;
use rss;
use reqwest;
use r2d2;
@ -8,7 +8,7 @@ use std::io;
error_chain! {
foreign_links {
R2D2TimeoutError(r2d2::GetTimeout);
R2D2Error(r2d2::Error);
DieselResultError(result::Error);
DieselMigrationError(RunMigrationsError);
RSSError(rss::Error);

View File

@ -4,7 +4,7 @@ use rayon::prelude::*;
use diesel::prelude::*;
use rayon::iter::IntoParallelIterator;
use diesel::Identifiable;
use diesel::associations::Identifiable;
use rss;
use dbqueries;
@ -276,13 +276,12 @@ mod tests {
f2.get_episodes().unwrap()
};
eps1.into_par_iter()
.zip(eps2)
.into_par_iter()
.for_each(|(ep1, ep2): (Episode, Episode)| {
eps1.into_par_iter().zip(eps2).into_par_iter().for_each(
|(ep1, ep2): (Episode, Episode)| {
assert_eq!(ep1, ep2);
assert_eq!(ep1.id(), ep2.id());
assert_eq!(ep1.podcast_id(), ep2.podcast_id());
});
},
);
}
}

View File

@ -1,5 +1,4 @@
#![recursion_limit = "1024"]
#![deny(missing_docs)]
#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
#![cfg_attr(feature = "clippy",
warn(option_unwrap_used, result_unwrap_used, print_stdout,
@ -11,6 +10,15 @@
//! A libraty for parsing, indexing and retrieving podcast Feeds,
//! into and from a Database.
#![deny(bad_style, const_err, dead_code, improper_ctypes, legacy_directory_ownership,
non_shorthand_field_patterns, no_mangle_generic_items, overflowing_literals,
path_statements, patterns_in_fns_without_body, plugin_as_library, private_in_public,
private_no_mangle_fns, private_no_mangle_statics, safe_extern_statics,
unconditional_recursion, unions_with_drop_fields, unused, unused_allocation,
unused_comparisons, unused_parens, while_true)]
#![deny(missing_debug_implementations, missing_docs, trivial_casts, trivial_numeric_casts,
unused_extern_crates)]
#[macro_use]
extern crate error_chain;
@ -22,9 +30,14 @@ extern crate log;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
#[macro_use]
extern crate diesel_migrations;
#[macro_use]
extern crate derive_builder;
extern crate ammonia;
extern crate chrono;
extern crate r2d2;
extern crate r2d2_diesel;
@ -49,6 +62,7 @@ mod schema;
pub use models::queryables::{Episode, Podcast, Source};
/// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths.
#[allow(missing_debug_implementations)]
pub mod xdg_dirs {
use std::path::PathBuf;
use xdg;

View File

@ -1,3 +1,5 @@
#![allow(unused_mut)]
use diesel::prelude::*;
use schema::{episode, podcast, source};
@ -20,7 +22,10 @@ trait Update {
#[derive(Insertable)]
#[table_name = "source"]
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default, Builder)]
#[builder(default)]
#[builder(derive(Debug))]
#[builder(setter(into))]
pub(crate) struct NewSource {
uri: String,
last_modified: Option<String>,
@ -63,15 +68,15 @@ impl NewSource {
#[derive(Insertable, AsChangeset)]
#[table_name = "podcast"]
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default, Builder)]
#[builder(default)]
#[builder(derive(Debug))]
#[builder(setter(into))]
pub(crate) struct NewPodcast {
title: String,
link: String,
description: String,
image_uri: Option<String>,
favorite: bool,
archive: bool,
always_dl: bool,
source_id: i32,
}
@ -124,78 +129,6 @@ impl NewPodcast {
}
}
#[derive(Debug, Default)]
pub(crate) struct NewPodcastBuilder {
title: String,
link: String,
description: String,
image_uri: Option<String>,
favorite: bool,
archive: bool,
always_dl: bool,
source_id: i32,
}
#[allow(dead_code)]
impl NewPodcastBuilder {
pub(crate) fn new() -> NewPodcastBuilder {
NewPodcastBuilder::default()
}
pub(crate) fn title(mut self, s: String) -> NewPodcastBuilder {
self.title = s;
self
}
pub(crate) fn link(mut self, s: String) -> NewPodcastBuilder {
self.link = s;
self
}
pub(crate) fn description(mut self, s: String) -> NewPodcastBuilder {
self.description = s;
self
}
pub(crate) fn image_uri(mut self, s: Option<String>) -> NewPodcastBuilder {
self.image_uri = s;
self
}
pub(crate) fn source_id(mut self, s: i32) -> NewPodcastBuilder {
self.source_id = s;
self
}
pub(crate) fn favorite(mut self, s: bool) -> NewPodcastBuilder {
self.favorite = s;
self
}
pub(crate) fn archive(mut self, s: bool) -> NewPodcastBuilder {
self.archive = s;
self
}
pub(crate) fn always_dl(mut self, s: bool) -> NewPodcastBuilder {
self.always_dl = s;
self
}
pub(crate) fn build(self) -> NewPodcast {
NewPodcast {
title: self.title,
link: self.link,
description: self.description,
image_uri: self.image_uri,
favorite: self.favorite,
archive: self.archive,
always_dl: self.always_dl,
source_id: self.source_id,
}
}
}
#[allow(dead_code)]
// Ignore the following geters. They are used in unit tests mainly.
impl NewPodcast {
@ -222,19 +155,18 @@ impl NewPodcast {
#[derive(Insertable, AsChangeset)]
#[table_name = "episode"]
#[derive(Debug, Clone, Default)]
#[derive(Debug, Clone, Default, Builder)]
#[builder(default)]
#[builder(derive(Debug))]
#[builder(setter(into))]
pub(crate) struct NewEpisode {
title: Option<String>,
uri: String,
local_uri: Option<String>,
description: Option<String>,
published_date: Option<String>,
length: Option<i32>,
guid: Option<String>,
epoch: i32,
played: Option<i32>,
favorite: bool,
archive: bool,
podcast_id: i32,
}
@ -256,8 +188,6 @@ impl Update for NewEpisode {
}
impl NewEpisode {
// TODO: Currently using diesel from master git.
// Watch out for v0.99.0 beta and change the toml.
// TODO: Refactor into batch indexes instead.
pub(crate) fn into_episode(self, con: &SqliteConnection) -> Result<Episode> {
self.index(con)?;
@ -287,108 +217,8 @@ impl NewEpisode {
}
}
#[derive(Debug, Default)]
pub(crate) struct NewEpisodeBuilder {
title: Option<String>,
uri: String,
local_uri: Option<String>,
description: Option<String>,
published_date: Option<String>,
length: Option<i32>,
guid: Option<String>,
epoch: i32,
played: Option<i32>,
favorite: bool,
archive: bool,
podcast_id: i32,
}
#[allow(dead_code)]
impl NewEpisodeBuilder {
pub(crate) fn new() -> NewEpisodeBuilder {
NewEpisodeBuilder::default()
}
pub(crate) fn title(mut self, s: Option<String>) -> NewEpisodeBuilder {
self.title = s;
self
}
pub(crate) fn uri(mut self, s: String) -> NewEpisodeBuilder {
self.uri = s;
self
}
pub(crate) fn local_uri(mut self, s: Option<String>) -> NewEpisodeBuilder {
self.local_uri = s;
self
}
pub(crate) fn description(mut self, s: Option<String>) -> NewEpisodeBuilder {
self.description = s;
self
}
pub(crate) fn published_date(mut self, s: Option<String>) -> NewEpisodeBuilder {
self.published_date = s;
self
}
pub(crate) fn length(mut self, s: Option<i32>) -> NewEpisodeBuilder {
self.length = s;
self
}
pub(crate) fn played(mut self, s: Option<i32>) -> NewEpisodeBuilder {
self.played = s;
self
}
pub(crate) fn guid(mut self, s: Option<String>) -> NewEpisodeBuilder {
self.guid = s;
self
}
pub(crate) fn epoch(mut self, s: i32) -> NewEpisodeBuilder {
self.epoch = s;
self
}
pub(crate) fn podcast_id(mut self, s: i32) -> NewEpisodeBuilder {
self.podcast_id = s;
self
}
pub(crate) fn favorite(mut self, s: bool) -> NewEpisodeBuilder {
self.favorite = s;
self
}
pub(crate) fn archive(mut self, s: bool) -> NewEpisodeBuilder {
self.archive = s;
self
}
pub(crate) fn build(self) -> NewEpisode {
NewEpisode {
title: self.title,
uri: self.uri,
local_uri: self.local_uri,
description: self.description,
published_date: self.published_date,
length: self.length,
guid: self.guid,
epoch: self.epoch,
played: self.played,
favorite: self.favorite,
archive: self.archive,
podcast_id: self.podcast_id,
}
}
}
#[allow(dead_code)]
// Ignore the following geters. They are used in unit tests mainly.
// Ignore the following getters. They are used in unit tests mainly.
impl NewEpisode {
pub(crate) fn title(&self) -> Option<&str> {
self.title.as_ref().map(|s| s.as_str())

View File

@ -342,9 +342,9 @@ impl<'a> Source {
let lmod = headers.get::<LastModified>();
// FIXME: This dsnt work most of the time apparently
if self.http_etag() != etag.map(|x| x.tag())
|| self.last_modified != lmod.map(|x| format!("{}", x))
{
if self.http_etag() != etag.map(|x| x.tag()) || self.last_modified != lmod.map(|x| {
format!("{}", x)
}) {
self.http_etag = etag.map(|x| x.tag().to_string().to_owned());
self.last_modified = lmod.map(|x| format!("{}", x));
self.save()?;

View File

@ -1,3 +1,4 @@
use ammonia;
use rss::{Channel, Item};
use rfc822_sanitizer::parse_from_rfc2822_with_fallback;
@ -9,10 +10,10 @@ use errors::*;
// TODO: Extend the support for parsing itunes extensions
/// Parses a `rss::Channel` into a `NewPodcast` Struct.
pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast {
let title = chan.title().trim().to_owned();
let description = chan.description().trim().to_owned();
let title = chan.title().trim();
let description = ammonia::clean(chan.description().trim());
let link = url_cleaner(chan.link()).to_owned();
let link = url_cleaner(chan.link());
let x = chan.itunes_ext().map(|s| s.image());
let image_uri = if let Some(img) = x {
img.map(|s| url_cleaner(s))
@ -20,19 +21,20 @@ pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast {
chan.image().map(|foo| url_cleaner(foo.url()))
};
NewPodcastBuilder::new()
NewPodcastBuilder::default()
.title(title)
.description(description)
.link(link)
.image_uri(image_uri)
.source_id(source_id)
.build()
.unwrap()
}
/// Parses an `rss::Item` into a `NewEpisode` Struct.
pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result<NewEpisode> {
let title = item.title().map(|s| s.trim().to_owned());
let description = item.description().map(|s| s.trim().to_owned());
let description = item.description().map(|s| ammonia::clean(s.trim()));
let guid = item.guid().map(|s| s.value().trim().to_owned());
// Its kinda weird this being an Option type.
@ -60,8 +62,7 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result<NewEpisode> {
let length = item.enclosure().map(|x| x.length().parse().unwrap_or(0));
Ok(
NewEpisodeBuilder::new()
Ok(NewEpisodeBuilder::default()
.title(title)
.uri(uri)
.description(description)
@ -70,8 +71,8 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result<NewEpisode> {
.epoch(epoch)
.guid(guid)
.podcast_id(parent_id)
.build(),
)
.build()
.unwrap())
}
@ -274,10 +275,10 @@ mod tests {
let channel = Channel::read_from(BufReader::new(file)).unwrap();
let firstitem = channel.items().first().unwrap();
let descr =
"Audit your network with a couple of easy commands on Kali Linux. Chris decides to \
blow off a little steam by attacking his IoT devices, Wes has the scope on Equifax \
blaming open source & the Beard just saved the show. Its a really packed episode!";
let descr = "Audit your network with a couple of easy commands on Kali Linux. Chris \
decides to blow off a little steam by attacking his IoT devices, Wes has the \
scope on Equifax blaming open source &amp; the Beard just saved the show. \
Its a really packed episode!";
let i = new_episode(&firstitem, 0).unwrap();
assert_eq!(i.title(), Some("Hacking Devices with Kali Linux | LUP 214"));
@ -299,7 +300,7 @@ mod tests {
decisions for the next version of Gnome have us worried about the \
future.</p>\n\n<p>Plus we chat with Wimpy about the Ubuntu Rally in NYC, \
Microsofts sneaky move to turn Windows 10 into the ULTIMATE LINUX \
RUNTIME, community news & more!</p>";
RUNTIME, community news &amp; more!</p>";
assert_eq!(i2.title(), Some("Gnome Does it Again | LUP 213"));
assert_eq!(
i2.uri(),
@ -318,9 +319,8 @@ mod tests {
let channel = Channel::read_from(BufReader::new(file)).unwrap();
let firstitem = channel.items().iter().nth(9).unwrap();
let descr = "This week we look at <a \
href=\"https://github.com/rust-lang/rfcs/pull/2094\">RFC 2094</a> \
\"Non-lexical lifetimes\"";
let descr = "This week we look at <a href=\"https://github.com/rust-lang/rfcs/pull/2094\" \
rel=\"noopener noreferrer\">RFC 2094</a> \"Non-lexical lifetimes\"";
let i = new_episode(&firstitem, 0).unwrap();
assert_eq!(i.title(), Some("Episode #9 - A Once in a Lifetime RFC"));
@ -342,8 +342,9 @@ mod tests {
let i2 = new_episode(&second, 0).unwrap();
let descr2 = "This week we look at <a \
href=\"https://github.com/rust-lang/rfcs/pull/2071\">RFC 2071</a> \"Add \
impl Trait type alias and variable declarations\"";
href=\"https://github.com/rust-lang/rfcs/pull/2071\" rel=\"noopener \
noreferrer\">RFC 2071</a> \"Add impl Trait type alias and variable \
declarations\"";
assert_eq!(i2.title(), Some("Episode #8 - An Existential Crisis"));
assert_eq!(
i2.uri(),

View File

@ -105,6 +105,16 @@ pub fn url_cleaner(s: &str) -> String {
}
}
/// Placeholder
// TODO: Docs
pub fn replace_extra_spaces(s: &str) -> String {
s.lines()
.map(|x| x.split_whitespace().collect::<Vec<_>>().join(" "))
.filter(|x| !x.is_empty())
.collect::<Vec<_>>()
.join("\n")
}
#[cfg(test)]
mod tests {
extern crate tempdir;
@ -129,20 +139,29 @@ mod tests {
// Setup episodes
let db = connection();
let con = db.get().unwrap();
NewEpisodeBuilder::new()
NewEpisodeBuilder::default()
.uri("foo_bar".to_string())
.local_uri(Some(valid_path.to_str().unwrap().to_owned()))
.build()
.unwrap()
.into_episode(&con)
.unwrap();
NewEpisodeBuilder::new()
NewEpisodeBuilder::default()
.uri("bar_baz".to_string())
.local_uri(Some(bad_path.to_str().unwrap().to_owned()))
.build()
.unwrap()
.into_episode(&con)
.unwrap();
let mut ep1 = dbqueries::get_episode_from_uri(&con, "foo_bar").unwrap();
let mut ep2 = dbqueries::get_episode_from_uri(&con, "bar_baz").unwrap();
ep1.set_local_uri(Some(valid_path.to_str().unwrap()));
ep2.set_local_uri(Some(bad_path.to_str().unwrap()));
drop(con);
ep1.save().unwrap();
ep2.save().unwrap();
tmp_dir
}
@ -232,4 +251,22 @@ mod tests {
assert_eq!(url_cleaner(good_url), good_url);
assert_eq!(url_cleaner(&format!(" {}\t\n", bad_url)), good_url);
}
#[test]
fn test_whitespace() {
let bad_txt = "1 2 3 4 5";
let valid_txt = "1 2 3 4 5";
assert_eq!(replace_extra_spaces(&bad_txt), valid_txt);
let bad_txt = "1 2 3 \n 4 5\n";
let valid_txt = "1 2 3\n4 5";
assert_eq!(replace_extra_spaces(&bad_txt), valid_txt);
let bad_txt = "1 2 3 \n\n\n \n 4 5\n";
let valid_txt = "1 2 3\n4 5";
assert_eq!(replace_extra_spaces(&bad_txt), valid_txt);
}
}

View File

@ -8,13 +8,13 @@ workspace = "../"
error-chain = "0.11.0"
hyper = "0.11.7"
log = "0.3.8"
mime_guess = "1.8.2"
mime_guess = "1.8.3"
reqwest = "0.8.1"
tempdir = "0.3.5"
[dependencies.diesel]
features = ["sqlite"]
git = "https://github.com/diesel-rs/diesel.git"
version = "0.99"
[dependencies.hammond-data]
path = "../hammond-data"

View File

@ -38,24 +38,7 @@ fn download_into(dir: &str, file_title: &str, url: &str) -> Result<String> {
ct_len.map(|x| info!("File Lenght: {}", x));
ct_type.map(|x| info!("Content Type: {}", x));
// This could be prettier.
// Determine the file extension from the http content-type header.
let ext = if let Some(t) = ct_type {
let mime = mime_guess::get_extensions(t.type_().as_ref(), t.subtype().as_ref());
if let Some(m) = mime {
if m.contains(&t.subtype().as_ref()) {
t.subtype().as_ref().to_string()
} else {
m.first().unwrap().to_string()
}
} else {
error!("Unkown mime type. {}", t);
"unkown".to_string()
}
} else {
error!("Unkown mime type.");
"unkown".to_string()
};
let ext = get_ext(ct_type.cloned()).unwrap_or(String::from("unkown"));
info!("Extension: {}", ext);
// Construct a temp file to save desired content.
@ -74,6 +57,20 @@ fn download_into(dir: &str, file_title: &str, url: &str) -> Result<String> {
Ok(target)
}
// Determine the file extension from the http content-type header.
fn get_ext(content: Option<ContentType>) -> Option<String> {
let cont = content.clone()?;
content
.and_then(|c| mime_guess::get_extensions(c.type_().as_ref(), c.subtype().as_ref()))
.and_then(|c| {
if c.contains(&cont.subtype().as_ref()) {
Some(cont.subtype().as_ref().to_string())
} else {
Some(c.first().unwrap().to_string())
}
})
}
// TODO: Write unit-tests.
/// Handles the I/O of fetching a remote file and saving into a Buffer and A File.
fn save_io(file: &str, resp: &mut reqwest::Response, content_lenght: Option<u64>) -> Result<()> {
@ -185,7 +182,7 @@ mod tests {
use hammond_data::Source;
use hammond_data::feed::index;
use hammond_data::dbqueries;
use diesel::Identifiable;
use diesel::associations::Identifiable;
use std::fs;

View File

@ -12,17 +12,14 @@ gdk-pixbuf = "0.3.0"
gio = "0.3.0"
glib = "0.4.0"
log = "0.3.8"
loggerv = "0.5.1"
loggerv = "0.6.0"
open = "1.2.1"
rayon = "0.9.0"
regex = "0.2.3"
[dependencies.diesel]
features = ["sqlite"]
git = "https://github.com/diesel-rs/diesel.git"
[dependencies.diesel_codegen]
features = ["sqlite"]
git = "https://github.com/diesel-rs/diesel.git"
version = "0.99.0"
[dependencies.gtk]
features = ["v3_22"]

View File

@ -3,7 +3,6 @@
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkPopover" id="add-popover">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Add a new feed</property>
<property name="valign">center</property>

View File

@ -109,7 +109,6 @@ Warn: This will delete downloaded content associated with this Podcast.</propert
</child>
<child>
<object class="GtkButton" id="mark_all_played_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Mark all episodes as Played.</property>

View File

@ -12,7 +12,7 @@
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport">
<object class="GtkViewport" id="viewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>

269
hammond-gtk/src/content.rs Normal file
View File

@ -0,0 +1,269 @@
use gtk;
use gtk::prelude::*;
use hammond_data::Podcast;
use hammond_data::dbqueries;
use widgets::podcast::PodcastWidget;
use views::podcasts::PopulatedView;
use views::empty::EmptyView;
#[derive(Debug)]
pub struct Content {
pub stack: gtk::Stack,
pub widget: PodcastWidget,
pub podcasts: PopulatedView,
pub empty: EmptyView,
}
impl Content {
pub fn new() -> Content {
let stack = gtk::Stack::new();
let widget = PodcastWidget::new();
let podcasts = PopulatedView::new();
let empty = EmptyView::new();
stack.add_named(&widget.container, "widget");
stack.add_named(&podcasts.container, "podcasts");
stack.add_named(&empty.container, "empty");
Content {
stack,
widget,
empty,
podcasts,
}
}
pub fn new_initialized() -> Content {
let ct = Content::new();
ct.init();
ct
}
pub fn init(&self) {
self.podcasts.init(&self.stack);
if self.podcasts.flowbox.get_children().is_empty() {
self.stack.set_visible_child_name("empty");
return;
}
self.stack.set_visible_child_name("podcasts");
}
fn replace_widget(&mut self, pdw: PodcastWidget) {
let vis = self.stack.get_visible_child_name().unwrap();
let old = self.stack.get_child_by_name("widget").unwrap();
self.stack.remove(&old);
self.widget = pdw;
self.stack.add_named(&self.widget.container, "widget");
self.stack.set_visible_child_name(&vis);
old.destroy();
}
fn replace_podcasts(&mut self, pop: PopulatedView) {
let vis = self.stack.get_visible_child_name().unwrap();
let old = self.stack.get_child_by_name("podcasts").unwrap();
self.stack.remove(&old);
self.podcasts = pop;
self.stack.add_named(&self.podcasts.container, "podcasts");
self.stack.set_visible_child_name(&vis);
old.destroy();
}
}
#[derive(Debug)]
// Experiementing with Wrapping gtk::Stack into a State machine.
// Gonna revist it when TryInto trais is stabilized.
pub struct ContentState<S> {
content: Content,
state: S,
}
pub trait UpdateView {
fn update(&mut self);
}
#[derive(Debug)]
pub struct Empty {}
#[derive(Debug)]
pub struct PodcastsView {}
#[derive(Debug)]
pub struct WidgetsView {}
impl Into<ContentState<PodcastsView>> for ContentState<Empty> {
fn into(self) -> ContentState<PodcastsView> {
self.content.stack.set_visible_child_name("podcasts");
ContentState {
content: self.content,
state: PodcastsView {},
}
}
}
impl UpdateView for ContentState<Empty> {
fn update(&mut self) {}
}
impl Into<ContentState<Empty>> for ContentState<PodcastsView> {
fn into(self) -> ContentState<Empty> {
self.content.stack.set_visible_child_name("empty");
ContentState {
content: self.content,
state: Empty {},
}
}
}
impl Into<ContentState<WidgetsView>> for ContentState<PodcastsView> {
fn into(self) -> ContentState<WidgetsView> {
self.content.stack.set_visible_child_name("widget");
ContentState {
content: self.content,
state: WidgetsView {},
}
}
}
impl UpdateView for ContentState<PodcastsView> {
fn update(&mut self) {
let pop = PopulatedView::new_initialized(&self.content.stack);
self.content.replace_podcasts(pop)
}
}
impl Into<ContentState<PodcastsView>> for ContentState<WidgetsView> {
fn into(self) -> ContentState<PodcastsView> {
self.content.stack.set_visible_child_name("podcasts");
ContentState {
content: self.content,
state: PodcastsView {},
}
}
}
impl Into<ContentState<Empty>> for ContentState<WidgetsView> {
fn into(self) -> ContentState<Empty> {
self.content.stack.set_visible_child_name("empty");
ContentState {
content: self.content,
state: Empty {},
}
}
}
impl UpdateView for ContentState<WidgetsView> {
fn update(&mut self) {
let old = self.content.stack.get_child_by_name("widget").unwrap();
let id = WidgetExt::get_name(&old).unwrap();
let pd = dbqueries::get_podcast_from_id(id.parse::<i32>().unwrap()).unwrap();
let pdw = PodcastWidget::new_initialized(&self.content.stack, &pd);
self.content.replace_widget(pdw);
}
}
impl ContentState<PodcastsView> {
#[allow(dead_code)]
pub fn new() -> Result<ContentState<PodcastsView>, ContentState<Empty>> {
let content = Content::new();
content.podcasts.init(&content.stack);
if content.podcasts.flowbox.get_children().is_empty() {
content.stack.set_visible_child_name("empty");
return Err(ContentState {
content,
state: Empty {},
});
}
content.stack.set_visible_child_name("podcasts");
Ok(ContentState {
content,
state: PodcastsView {},
})
}
#[allow(dead_code)]
pub fn get_stack(&self) -> gtk::Stack {
self.content.stack.clone()
}
}
fn replace_widget(stack: &gtk::Stack, pdw: &PodcastWidget) {
let old = stack.get_child_by_name("widget").unwrap();
stack.remove(&old);
stack.add_named(&pdw.container, "widget");
old.destroy();
}
fn replace_podcasts(stack: &gtk::Stack, pop: &PopulatedView) {
let old = stack.get_child_by_name("podcasts").unwrap();
stack.remove(&old);
stack.add_named(&pop.container, "podcasts");
old.destroy();
}
#[allow(dead_code)]
pub fn show_widget(stack: &gtk::Stack) {
stack.set_visible_child_name("widget")
}
pub fn show_podcasts(stack: &gtk::Stack) {
stack.set_visible_child_name("podcasts")
}
pub fn show_empty(stack: &gtk::Stack) {
stack.set_visible_child_name("empty")
}
pub fn update_podcasts(stack: &gtk::Stack) {
let pods = PopulatedView::new_initialized(stack);
if pods.flowbox.get_children().is_empty() {
show_empty(stack)
}
replace_podcasts(stack, &pods);
}
pub fn update_widget(stack: &gtk::Stack, pd: &Podcast) {
let pdw = PodcastWidget::new_initialized(stack, pd);
replace_widget(stack, &pdw);
}
pub fn update_podcasts_preserve_vis(stack: &gtk::Stack) {
let vis = stack.get_visible_child_name().unwrap();
update_podcasts(stack);
if vis != "empty" {
stack.set_visible_child_name(&vis)
}
}
pub fn update_widget_preserve_vis(stack: &gtk::Stack, pd: &Podcast) {
let vis = stack.get_visible_child_name().unwrap();
update_widget(stack, pd);
stack.set_visible_child_name(&vis)
}
pub fn on_podcasts_child_activate(stack: &gtk::Stack, pd: &Podcast) {
update_widget(stack, pd);
stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft);
}
pub fn on_home_button_activate(stack: &gtk::Stack) {
let vis = stack.get_visible_child_name().unwrap();
if vis != "widget" {
update_podcasts(stack);
}
show_podcasts(stack);
}

View File

@ -4,57 +4,77 @@ use gtk::prelude::*;
use hammond_data::Source;
use hammond_data::utils::url_cleaner;
use podcasts_view::update_podcasts_view;
use utils;
use content;
pub fn get_headerbar(stack: &gtk::Stack) -> gtk::HeaderBar {
#[derive(Debug)]
pub struct Header {
pub container: gtk::HeaderBar,
home: gtk::Button,
refresh: gtk::Button,
add_toggle: gtk::MenuButton,
}
impl Header {
pub fn new() -> Header {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui");
let header: gtk::HeaderBar = builder.get_object("headerbar1").unwrap();
let home_button: gtk::Button = builder.get_object("homebutton").unwrap();
let refresh_button: gtk::Button = builder.get_object("refbutton").unwrap();
let home: gtk::Button = builder.get_object("homebutton").unwrap();
let refresh: gtk::Button = builder.get_object("refbutton").unwrap();
let add_toggle: gtk::MenuButton = builder.get_object("add-toggle-button").unwrap();
Header {
container: header,
home,
refresh,
add_toggle,
}
}
pub fn new_initialized(stack: &gtk::Stack) -> Header {
let header = Header::new();
header.init(stack);
header
}
fn init(&self, stack: &gtk::Stack) {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui");
let add_toggle_button: gtk::MenuButton = builder.get_object("add-toggle-button").unwrap();
let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap();
let new_url: gtk::Entry = builder.get_object("new-url").unwrap();
let add_button: gtk::Button = builder.get_object("add-button").unwrap();
// TODO: check if url exists in the db and lock the button
new_url.connect_changed(move |url| {
println!("{:?}", url.get_text());
});
add_button.connect_clicked(clone!(stack, add_popover => move |_| {
let url = new_url.get_text().unwrap_or_default();
let url = url_cleaner(&url);
on_add_bttn_clicked(&stack, &url);
add_button.connect_clicked(clone!(stack, add_popover, new_url => move |_| {
on_add_bttn_clicked(&stack, &new_url);
// TODO: lock the button instead of hiding and add notification of feed added.
// TODO: map the spinner
add_popover.hide();
}));
add_popover.hide();
add_toggle_button.set_popover(&add_popover);
self.add_toggle.set_popover(&add_popover);
// TODO: make it a back arrow button, that will hide when appropriate,
// and add a StackSwitcher when more views are added.
home_button.connect_clicked(clone!(stack => move |_| {
let vis = stack.get_visible_child_name().unwrap();
stack.set_visible_child_name("fb_parent");
if vis != "pdw" {
update_podcasts_view(&stack);
}
self.home.connect_clicked(clone!(stack => move |_| {
content::on_home_button_activate(&stack);
}));
// FIXME: There appears to be a memmory leak here.
refresh_button.connect_clicked(clone!(stack => move |_| {
self.refresh.connect_clicked(clone!(stack => move |_| {
utils::refresh_feed(&stack, None, None);
}));
header
}
}
fn on_add_bttn_clicked(stack: &gtk::Stack, url: &str) {
let source = Source::from_url(url);
fn on_add_bttn_clicked(stack: &gtk::Stack, entry: &gtk::Entry) {
let url = entry.get_text().unwrap_or_default();
let url = url_cleaner(&url);
let source = Source::from_url(&url);
if let Ok(s) = source {
info!("{:?} feed added", url);

View File

@ -12,6 +12,7 @@ extern crate hammond_downloader;
extern crate log;
extern crate loggerv;
extern crate open;
extern crate regex;
// extern crate rayon;
// use rayon::prelude::*;
@ -43,12 +44,11 @@ macro_rules! clone {
mod views;
mod widgets;
mod headerbar;
mod content;
mod utils;
mod static_resource;
use views::podcasts_view;
/*
THIS IS STILL A PROTOTYPE.
*/
@ -62,8 +62,13 @@ fn build_ui(app: &gtk::Application) {
// Get the main window
let window = gtk::ApplicationWindow::new(app);
window.set_default_size(1150, 650);
// Setup the Stack that will manage the switch between podcasts_view and podcast_widget.
let stack = podcasts_view::setup_stack();
// TODO: this will blow horribly
// let ct = content::ContentState::new().unwrap();
// let stack = ct.get_stack();
let ct = content::Content::new_initialized();
let stack = ct.stack;
window.add(&stack);
window.connect_delete_event(|w, _| {
@ -98,8 +103,8 @@ fn build_ui(app: &gtk::Application) {
});
// Get the headerbar
let header = headerbar::get_headerbar(&stack);
window.set_titlebar(&header);
let header = headerbar::Header::new_initialized(&stack);
window.set_titlebar(&header.container);
window.show_all();
window.activate();

View File

@ -1,14 +1,18 @@
use glib;
use gtk;
use gdk_pixbuf::Pixbuf;
use hammond_data::feed;
use hammond_data::Source;
use hammond_data::{Podcast, Source};
use hammond_downloader::downloader;
use std::{thread, time};
use std::cell::RefCell;
use std::sync::mpsc::{channel, Receiver};
use std::borrow::Cow;
use views::podcasts_view;
use content;
use regex::Regex;
type Foo = RefCell<Option<(gtk::Stack, Receiver<bool>)>>;
@ -55,9 +59,54 @@ fn refresh_podcasts_view() -> glib::Continue {
GLOBAL.with(|global| {
if let Some((ref stack, ref reciever)) = *global.borrow() {
if reciever.try_recv().is_ok() {
podcasts_view::update_podcasts_view(stack);
content::update_podcasts_preserve_vis(stack);
}
}
});
glib::Continue(false)
}
pub fn get_pixbuf_from_path(pd: &Podcast) -> Option<Pixbuf> {
let img_path = downloader::cache_image(pd)?;
Pixbuf::new_from_file_at_scale(&img_path, 256, 256, true).ok()
}
#[allow(dead_code)]
// WIP: parse html to markup
pub fn html_to_markup(s: &mut str) -> Cow<str> {
s.trim();
s.replace('&', "&amp;");
s.replace('<', "&lt;");
s.replace('>', "&gt;");
let re = Regex::new("(?P<url>https?://[^\\s&,)(\"]+(&\\w=[\\w._-]?)*(#[\\w._-]+)?)").unwrap();
re.replace_all(s, "<a href=\"$url\">$url</a>")
}
#[cfg(test)]
mod tests {
use hammond_data::Source;
use hammond_data::feed::index;
use hammond_data::dbqueries;
use diesel::associations::Identifiable;
use super::*;
#[test]
fn test_get_pixbuf_from_path() {
let url = "http://www.newrustacean.com/feed.xml";
// Create and index a source
let source = Source::from_url(url).unwrap();
// Copy it's id
let sid = source.id().clone();
// Convert Source it into a Feed and index it
let feed = source.into_feed().unwrap();
index(vec![feed]);
// Get the Podcast
let pd = dbqueries::get_podcast_from_source_id(sid).unwrap();
let pxbuf = get_pixbuf_from_path(&pd);
assert!(pxbuf.is_some());
}
}

View File

@ -0,0 +1,15 @@
use gtk;
#[derive(Debug, Clone)]
pub struct EmptyView {
pub container: gtk::Box,
}
impl EmptyView {
pub fn new() -> EmptyView {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_view.ui");
let view: gtk::Box = builder.get_object("empty_view").unwrap();
EmptyView { container: view }
}
}

View File

@ -1 +1,2 @@
pub mod podcasts_view;
pub mod podcasts;
pub mod empty;

View File

@ -0,0 +1,144 @@
use gtk;
use gtk::prelude::*;
use gdk_pixbuf::Pixbuf;
use diesel::associations::Identifiable;
use hammond_data::dbqueries;
use hammond_data::Podcast;
use utils::get_pixbuf_from_path;
use content;
#[derive(Debug, Clone)]
pub struct PopulatedView {
pub container: gtk::Box,
pub flowbox: gtk::FlowBox,
viewport: gtk::Viewport,
}
#[derive(Debug)]
struct PodcastChild {
container: gtk::Box,
title: gtk::Label,
cover: gtk::Image,
banner: gtk::Image,
number: gtk::Label,
child: gtk::FlowBoxChild,
}
impl PopulatedView {
pub fn new() -> PopulatedView {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_view.ui");
let container: gtk::Box = builder.get_object("fb_parent").unwrap();
let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap();
let viewport: gtk::Viewport = builder.get_object("viewport").unwrap();
PopulatedView {
container,
flowbox,
viewport,
}
}
#[allow(dead_code)]
pub fn new_initialized(stack: &gtk::Stack) -> PopulatedView {
let pop = PopulatedView::new();
pop.init(stack);
pop
}
pub fn init(&self, stack: &gtk::Stack) {
use gtk::WidgetExt;
// TODO: handle unwraps.
self.flowbox
.connect_child_activated(clone!(stack => move |_, child| {
// This is such an ugly hack...
// let id = child.get_name().unwrap().parse::<i32>().unwrap();
let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap();
let parent = dbqueries::get_podcast_from_id(id).unwrap();
on_flowbox_child_activate(&stack, &parent);
}));
// Populate the flowbox with the Podcasts.
self.populate_flowbox();
}
fn populate_flowbox(&self) {
let podcasts = dbqueries::get_podcasts();
if let Ok(pds) = podcasts {
pds.iter().for_each(|parent| {
let flowbox_child = PodcastChild::new_initialized(parent);
self.flowbox.add(&flowbox_child.child);
});
self.flowbox.show_all();
}
}
}
impl PodcastChild {
fn new() -> PodcastChild {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_child.ui");
// Copy of gnome-music AlbumWidget
let container: gtk::Box = builder.get_object("fb_child").unwrap();
let title: gtk::Label = builder.get_object("pd_title").unwrap();
let cover: gtk::Image = builder.get_object("pd_cover").unwrap();
let banner: gtk::Image = builder.get_object("banner").unwrap();
let number: gtk::Label = builder.get_object("banner_label").unwrap();
let child = gtk::FlowBoxChild::new();
child.add(&container);
PodcastChild {
container,
title,
cover,
banner,
number,
child,
}
}
fn init(&self, pd: &Podcast) {
self.title.set_text(pd.title());
let cover = get_pixbuf_from_path(pd);
if let Some(img) = cover {
self.cover.set_from_pixbuf(&img);
};
WidgetExt::set_name(&self.child, &pd.id().to_string());
self.configure_banner(pd);
}
pub fn new_initialized(pd: &Podcast) -> PodcastChild {
let child = PodcastChild::new();
child.init(pd);
child
}
fn configure_banner(&self, pd: &Podcast) {
let bann =
Pixbuf::new_from_resource_at_scale("/org/gnome/hammond/banner.png", 256, 256, true);
if let Ok(b) = bann {
self.banner.set_from_pixbuf(&b);
let new_episodes = dbqueries::get_pd_unplayed_episodes(pd);
if let Ok(n) = new_episodes {
if !n.is_empty() {
self.number.set_text(&n.len().to_string());
self.banner.show();
self.number.show();
}
}
}
}
}
fn on_flowbox_child_activate(stack: &gtk::Stack, parent: &Podcast) {
content::on_podcasts_child_activate(stack, parent)
}

View File

@ -1,152 +0,0 @@
use gtk;
use gtk::prelude::*;
use gdk_pixbuf::Pixbuf;
use diesel::associations::Identifiable;
use hammond_data::dbqueries;
use hammond_data::Podcast;
use widgets::podcast::*;
fn setup_empty_view(stack: &gtk::Stack) {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_view.ui");
let view: gtk::Box = builder.get_object("empty_view").unwrap();
stack.add_named(&view, "empty");
}
fn show_empty_view(stack: &gtk::Stack) {
stack.set_visible_child_name("empty");
info!("Empty view.");
}
fn populate_flowbox(flowbox: &gtk::FlowBox) {
let podcasts = dbqueries::get_podcasts();
if let Ok(pds) = podcasts {
pds.iter().for_each(|parent| {
let f = create_flowbox_child(parent);
flowbox.add(&f);
});
flowbox.show_all();
}
}
fn create_flowbox_child(pd: &Podcast) -> gtk::FlowBoxChild {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_child.ui");
// Copy of gnome-music AlbumWidget
let box_: gtk::Box = builder.get_object("fb_child").unwrap();
let pd_title: gtk::Label = builder.get_object("pd_title").unwrap();
let pd_cover: gtk::Image = builder.get_object("pd_cover").unwrap();
let banner: gtk::Image = builder.get_object("banner").unwrap();
let banner_title: gtk::Label = builder.get_object("banner_label").unwrap();
pd_title.set_text(pd.title());
let cover = get_pixbuf_from_path(pd);
if let Some(img) = cover {
pd_cover.set_from_pixbuf(&img);
};
configure_banner(pd, &banner, &banner_title);
let fbc = gtk::FlowBoxChild::new();
// There's probably a better way to store the id somewhere.
// fbc.set_name(&pd.id().to_string());
WidgetExt::set_name(&fbc, &pd.id().to_string());
fbc.add(&box_);
fbc
}
fn configure_banner(pd: &Podcast, banner: &gtk::Image, banner_title: &gtk::Label) {
let bann = Pixbuf::new_from_resource_at_scale("/org/gnome/hammond/banner.png", 256, 256, true);
if let Ok(b) = bann {
banner.set_from_pixbuf(&b);
let new_episodes = dbqueries::get_pd_unplayed_episodes(pd);
if let Ok(n) = new_episodes {
if !n.is_empty() {
banner_title.set_text(&n.len().to_string());
banner.show();
banner_title.show();
}
}
}
}
fn on_flowbox_child_activate(stack: &gtk::Stack, parent: &Podcast) {
let old = stack.get_child_by_name("pdw").unwrap();
let pdw = podcast_widget(stack, parent);
stack.remove(&old);
stack.add_named(&pdw, "pdw");
stack.set_visible_child(&pdw);
// aggresive memory cleanup
// probably not needed
old.destroy();
}
fn setup_podcasts_flowbox(stack: &gtk::Stack) -> gtk::FlowBox {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_view.ui");
let fb_parent: gtk::Box = builder.get_object("fb_parent").unwrap();
let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap();
init_flowbox(stack, &flowbox);
stack.add_named(&fb_parent, "fb_parent");
if flowbox.get_children().is_empty() {
show_empty_view(stack);
} else {
stack.set_visible_child(&fb_parent);
};
flowbox
}
pub fn setup_stack() -> gtk::Stack {
let stack = gtk::Stack::new();
stack.set_transition_type(gtk::StackTransitionType::SlideLeftRight);
setup_empty_view(&stack);
setup_podcast_widget(&stack);
setup_podcasts_flowbox(&stack);
stack
}
pub fn update_podcasts_view(stack: &gtk::Stack) {
let vis = stack.get_visible_child_name().unwrap();
let old = stack.get_child_by_name("fb_parent").unwrap();
stack.remove(&old);
let flowbox = setup_podcasts_flowbox(stack);
if vis == "empty" && !flowbox.get_children().is_empty() {
stack.set_visible_child_name("fb_parent");
} else if vis == "fb_parent" && flowbox.get_children().is_empty() {
stack.set_visible_child_name("empty");
} else {
// preserve the visible widget
stack.set_visible_child_name(&vis);
};
// aggresive memory cleanup
// probably not needed
old.destroy();
}
fn init_flowbox(stack: &gtk::Stack, flowbox: &gtk::FlowBox) {
use gtk::WidgetExt;
// TODO: handle unwraps.
flowbox.connect_child_activated(clone!(stack => move |_, child| {
// This is such an ugly hack...
// let id = child.get_name().unwrap().parse::<i32>().unwrap();
let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap();
let parent = dbqueries::get_podcast_from_id(id).unwrap();
on_flowbox_child_activate(&stack, &parent);
}));
// Populate the flowbox with the Podcasts.
populate_flowbox(flowbox);
}

View File

@ -1,115 +1,170 @@
use glib;
use gtk;
use gtk::prelude::*;
use gtk::{ContainerExt, TextBufferExt};
use open;
use dissolve::strip_html_tags;
use diesel::associations::Identifiable;
use hammond_data::dbqueries;
use hammond_data::{Episode, Podcast};
use hammond_downloader::downloader;
use hammond_data::utils::*;
use hammond_data::errors::*;
use hammond_data::utils::replace_extra_spaces;
use dissolve::strip_html_tags;
use diesel::associations::Identifiable;
// use utils::html_to_markup;
use std::thread;
use std::cell::RefCell;
use std::sync::mpsc::{channel, Receiver};
use std::path::Path;
use glib;
use gtk;
use gtk::prelude::*;
use gtk::{ContainerExt, TextBufferExt};
type Foo = RefCell<Option<(gtk::Button, gtk::Button, gtk::Button, Receiver<bool>)>>;
thread_local!(static GLOBAL: Foo = RefCell::new(None));
fn epidose_widget(episode: &mut Episode, pd_title: &str) -> gtk::Box {
#[derive(Debug)]
struct EpisodeWidget {
container: gtk::Box,
download: gtk::Button,
play: gtk::Button,
delete: gtk::Button,
played: gtk::Button,
unplayed: gtk::Button,
title: gtk::Label,
description: gtk::TextView,
// description: gtk::Label,
expander: gtk::Expander,
}
impl EpisodeWidget {
fn new() -> EpisodeWidget {
// This is just a prototype and will be reworked probably.
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episode_widget.ui");
let ep: gtk::Box = builder.get_object("episode_box").unwrap();
let download_button: gtk::Button = builder.get_object("download_button").unwrap();
let play_button: gtk::Button = builder.get_object("play_button").unwrap();
let delete_button: gtk::Button = builder.get_object("delete_button").unwrap();
let played_button: gtk::Button = builder.get_object("mark_played_button").unwrap();
let unplayed_button: gtk::Button = builder.get_object("mark_unplayed_button").unwrap();
let container: gtk::Box = builder.get_object("episode_box").unwrap();
let download: gtk::Button = builder.get_object("download_button").unwrap();
let play: gtk::Button = builder.get_object("play_button").unwrap();
let delete: gtk::Button = builder.get_object("delete_button").unwrap();
let played: gtk::Button = builder.get_object("mark_played_button").unwrap();
let unplayed: gtk::Button = builder.get_object("mark_unplayed_button").unwrap();
let title_label: gtk::Label = builder.get_object("title_label").unwrap();
// let desc_label: gtk::Label = builder.get_object("desc_label").unwrap();
let title: gtk::Label = builder.get_object("title_label").unwrap();
let expander: gtk::Expander = builder.get_object("expand_desc").unwrap();
let desc_text_view: gtk::TextView = builder.get_object("desc_text_view").unwrap();
let description: gtk::TextView = builder.get_object("desc_text_view").unwrap();
// let description: gtk::Label = builder.get_object("desc_text").unwrap();
title_label.set_xalign(0.0);
EpisodeWidget {
container,
download,
play,
delete,
played,
unplayed,
title,
expander,
description,
}
}
pub fn new_initialized(episode: &mut Episode, pd: &Podcast) -> EpisodeWidget {
let widget = EpisodeWidget::new();
widget.init(episode, pd);
widget
}
fn init(&self, episode: &mut Episode, pd: &Podcast) {
self.title.set_xalign(0.0);
if let Some(t) = episode.title() {
title_label.set_text(t);
self.title.set_text(t);
}
if episode.description().is_some() {
let d = episode.description().unwrap().to_owned();
let text = episode.description().unwrap().to_owned();
let description = &self.description;
self.expander
.connect_activate(clone!(description, text => move |_| {
// let mut text = text.clone();
// html_to_markup(&mut text);
// description.set_markup(&text)
expander.connect_activate(move |_| {
let plain_text = strip_html_tags(&d).join(" ");
let plain_text = strip_html_tags(&text).join(" ");
// TODO: handle unwrap
let buff = desc_text_view.get_buffer().unwrap();
buff.set_text(plain_text.trim());
});
let buff = description.get_buffer().unwrap();
buff.set_text(&replace_extra_spaces(&plain_text));
}));
}
if episode.played().is_some() {
unplayed_button.show();
played_button.hide();
self.unplayed.show();
self.played.hide();
}
// Show or hide the play/delete/download buttons upon widget initialization.
let local_uri = episode.local_uri();
if local_uri.is_some() && Path::new(local_uri.unwrap()).exists() {
download_button.hide();
play_button.show();
delete_button.show();
self.download.hide();
self.play.show();
self.delete.show();
}
play_button.connect_clicked(clone!(episode, played_button, unplayed_button => move |_| {
let played = &self.played;
let unplayed = &self.unplayed;
self.play
.connect_clicked(clone!(episode, played, unplayed => move |_| {
let mut episode = episode.clone();
on_play_bttn_clicked(*episode.id());
let _ = episode.set_played_now();
played_button.hide();
unplayed_button.show();
played.hide();
unplayed.show();
}));
delete_button.connect_clicked(clone!(episode, play_button, download_button => move |del| {
let play = &self.play;
let download = &self.download;
self.delete
.connect_clicked(clone!(episode, play, download => move |del| {
on_delete_bttn_clicked(*episode.id());
del.hide();
play_button.hide();
download_button.show();
play.hide();
download.show();
}));
played_button.connect_clicked(clone!(episode, unplayed_button => move |played| {
let unplayed = &self.unplayed;
self.played
.connect_clicked(clone!(episode, unplayed => move |played| {
let mut episode = episode.clone();
let _ = episode.set_played_now();
played.hide();
unplayed_button.show();
unplayed.show();
}));
unplayed_button.connect_clicked(clone!(episode, played_button => move |un| {
let played = &self.played;
self.unplayed
.connect_clicked(clone!(episode, played => move |un| {
let mut episode = episode.clone();
episode.set_played(None);
let _ = episode.save();
un.hide();
played_button.show();
played.show();
}));
let pd_title = pd_title.to_owned();
download_button.connect_clicked(clone!(play_button, delete_button, episode => move |dl| {
let pd_title = pd.title().to_owned();
let play = &self.play;
let delete = &self.delete;
self.download
.connect_clicked(clone!(play, delete, episode => move |dl| {
on_download_clicked(
&pd_title,
&mut episode.clone(),
dl,
&play_button,
&delete_button,
&play,
&delete,
);
}));
ep
}
}
// TODO: show notification when dl is finished.
@ -192,8 +247,9 @@ pub fn episodes_listbox(pd: &Podcast) -> Result<gtk::ListBox> {
let list = gtk::ListBox::new();
episodes.into_iter().for_each(|mut ep| {
let w = epidose_widget(&mut ep, pd.title());
list.add(&w)
// let w = epidose_widget(&mut ep, pd.title());
let widget = EpisodeWidget::new_initialized(&mut ep, pd);
list.add(&widget.container)
});
list.set_vexpand(false);

View File

@ -1,6 +1,6 @@
use gtk::prelude::*;
use gtk;
use gdk_pixbuf::Pixbuf;
use diesel::Identifiable;
use std::fs;
@ -9,48 +9,90 @@ use hammond_data::Podcast;
use hammond_downloader::downloader;
use widgets::episode::episodes_listbox;
use podcasts_view::update_podcasts_view;
use utils::get_pixbuf_from_path;
use content;
pub fn podcast_widget(stack: &gtk::Stack, pd: &Podcast) -> gtk::Box {
#[derive(Debug)]
pub struct PodcastWidget {
pub container: gtk::Box,
cover: gtk::Image,
title: gtk::Label,
description: gtk::TextView,
view: gtk::Viewport,
unsub: gtk::Button,
played: gtk::Button,
}
impl PodcastWidget {
pub fn new() -> PodcastWidget {
// Adapted from gnome-music AlbumWidget
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcast_widget.ui");
let pd_widget: gtk::Box = builder.get_object("podcast_widget").unwrap();
let container: gtk::Box = builder.get_object("podcast_widget").unwrap();
let cover: gtk::Image = builder.get_object("cover").unwrap();
let title_label: gtk::Label = builder.get_object("title_label").unwrap();
let desc_text_view: gtk::TextView = builder.get_object("desc_text_view").unwrap();
let title: gtk::Label = builder.get_object("title_label").unwrap();
let description: gtk::TextView = builder.get_object("desc_text_view").unwrap();
let view: gtk::Viewport = builder.get_object("view").unwrap();
let unsub_button: gtk::Button = builder.get_object("unsub_button").unwrap();
let played_button: gtk::Button = builder.get_object("mark_all_played_button").unwrap();
let unsub: gtk::Button = builder.get_object("unsub_button").unwrap();
let played: gtk::Button = builder.get_object("mark_all_played_button").unwrap();
PodcastWidget {
container,
cover,
title,
description,
view,
unsub,
played,
}
}
pub fn new_initialized(stack: &gtk::Stack, pd: &Podcast) -> PodcastWidget {
let pdw = PodcastWidget::new();
pdw.init(stack, pd);
pdw
}
pub fn init(&self, stack: &gtk::Stack, pd: &Podcast) {
WidgetExt::set_name(&self.container, &pd.id().to_string());
// TODO: should spawn a thread to avoid locking the UI probably.
unsub_button.connect_clicked(clone!(stack, pd => move |bttn| {
self.unsub.connect_clicked(clone!(stack, pd => move |bttn| {
on_unsub_button_clicked(&stack, &pd, bttn);
}));
title_label.set_text(pd.title());
self.title.set_text(pd.title());
let listbox = episodes_listbox(pd);
if let Ok(l) = listbox {
view.add(&l);
self.view.add(&l);
}
{
let buff = desc_text_view.get_buffer().unwrap();
let buff = self.description.get_buffer().unwrap();
buff.set_text(pd.description());
}
let img = get_pixbuf_from_path(pd);
if let Some(i) = img {
cover.set_from_pixbuf(&i);
self.cover.set_from_pixbuf(&i);
}
played_button.connect_clicked(clone!(stack, pd => move |_| {
self.played.connect_clicked(clone!(stack, pd => move |_| {
on_played_button_clicked(&stack, &pd);
}));
show_played_button(pd, &played_button);
self.show_played_button(pd);
}
pd_widget
fn show_played_button(&self, pd: &Podcast) {
let new_episodes = dbqueries::get_pd_unplayed_episodes(pd);
if let Ok(n) = new_episodes {
if !n.is_empty() {
self.played.show()
}
}
}
}
fn on_unsub_button_clicked(stack: &gtk::Stack, pd: &Podcast, unsub_button: &gtk::Button) {
@ -69,76 +111,12 @@ fn on_unsub_button_clicked(stack: &gtk::Stack, pd: &Podcast, unsub_button: &gtk:
}
};
}
stack.set_visible_child_name("fb_parent");
update_podcasts_view(stack);
content::update_podcasts(stack);
content::show_podcasts(stack);
}
fn on_played_button_clicked(stack: &gtk::Stack, pd: &Podcast) {
let _ = dbqueries::update_none_to_played_now(pd);
update_podcast_widget(stack, pd);
}
fn show_played_button(pd: &Podcast, played_button: &gtk::Button) {
let new_episodes = dbqueries::get_pd_unplayed_episodes(pd);
if let Ok(n) = new_episodes {
if !n.is_empty() {
played_button.show()
}
}
}
pub fn get_pixbuf_from_path(pd: &Podcast) -> Option<Pixbuf> {
let img_path = downloader::cache_image(pd);
if let Some(i) = img_path {
Pixbuf::new_from_file_at_scale(&i, 256, 256, true).ok()
} else {
None
}
}
pub fn setup_podcast_widget(stack: &gtk::Stack) {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcast_widget.ui");
let pd_widget: gtk::Box = builder.get_object("podcast_widget").unwrap();
stack.add_named(&pd_widget, "pdw");
}
pub fn update_podcast_widget(stack: &gtk::Stack, pd: &Podcast) {
let old = stack.get_child_by_name("pdw").unwrap();
let pdw = podcast_widget(stack, pd);
let vis = stack.get_visible_child_name().unwrap();
stack.remove(&old);
stack.add_named(&pdw, "pdw");
stack.set_visible_child_name(&vis);
old.destroy();
}
#[cfg(test)]
mod tests {
use hammond_data::Source;
use hammond_data::feed::index;
use diesel::Identifiable;
use super::*;
#[test]
fn test_get_pixbuf_from_path() {
let url = "http://www.newrustacean.com/feed.xml";
// Create and index a source
let source = Source::from_url(url).unwrap();
// Copy it's id
let sid = source.id().clone();
// Convert Source it into a Feed and index it
let feed = source.into_feed().unwrap();
index(vec![feed]);
// Get the Podcast
let pd = dbqueries::get_podcast_from_source_id(sid).unwrap();
let pxbuf = get_pixbuf_from_path(&pd);
assert!(pxbuf.is_some());
}
content::update_widget_preserve_vis(stack, pd);
}

View File

@ -14,18 +14,18 @@
"--talk-name=org.freedesktop.Notifications"
],
"build-options": {
"append-path": "/usr/lib/sdk/rust-stable/bin",
"build-args": [
"--share=network"
],
"env": {
"CARGO_HOME": "/run/build/Hammond/cargo"
},
"build-args": [ "--share=network" ]
}
},
"modules": [
{
"name": "Hammond",
"buildsystem": "simple",
"build-commands": [
"source /usr/lib/sdk/rust-stable/enable.sh && ./configure --prefix=/app && make && make install"
],
"buildsystem": "meson",
"sources": [
{
"type": "git",

View File

@ -1,3 +1,4 @@
unstable_features = true
verbose = false
disable_all_formatting = false
skip_children = false

View File

@ -12,14 +12,12 @@ mkdir -p $DIST
cp -rf hammond-data $DIST
cp -rf hammond-gtk $DIST
cp -rf hammond-downloader $DIST
cp build.rs $DIST
cp Cargo.toml $DIST
cp configure $DIST
cp meson.build $DIST
cp Hammond.doap $DIST
cp LICENSE $DIST
cp README.md $DIST
# cp -rf assets/org.gnome.Hammond.desktop $DIST
cp -rf assets $DIST
cp -rf scripts $DIST