Compare commits
55
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd52c5afdf | ||
|
|
dea517c17c | ||
|
|
6d93ceb910 | ||
|
|
9b0ac5b83d | ||
|
|
acabb40171 | ||
|
|
04cd56ca16 | ||
|
|
4371512ba2 | ||
|
|
ced686e1cd | ||
|
|
272aab2397 | ||
|
|
a7f87f2ac8 | ||
|
|
f9e85155a8 | ||
|
|
d281c18951 | ||
|
|
04e7f4f8a7 | ||
|
|
a090c11f4a | ||
|
|
c303c697a9 | ||
|
|
9466c5ea10 | ||
|
|
1268fcf1cc | ||
|
|
86d06fa879 | ||
|
|
cfe79a73d6 | ||
|
|
d7a9d9ddc8 | ||
|
|
b3d45384e1 | ||
|
|
64099e37e5 | ||
|
|
2fe612d392 | ||
|
|
14d72b92cb | ||
|
|
8c0055723c | ||
|
|
bb9e368b2d | ||
|
|
2c203acbd2 | ||
|
|
7115eb573c | ||
|
|
e626c6f286 | ||
|
|
24058f9534 | ||
|
|
a8d47e9a72 | ||
|
|
9a2f51b48d | ||
|
|
667deef5f2 | ||
|
|
aa349aa935 | ||
|
|
666ab01d03 | ||
|
|
ffbab0136f | ||
|
|
b5f7399b2c | ||
|
|
f1892eeba2 | ||
|
|
e7128a57db | ||
|
|
793cafd294 | ||
|
|
9b1097effe | ||
|
|
079ae0e1f3 | ||
|
|
e181a9837a | ||
|
|
ca5c7022ef | ||
|
|
75c50392cb | ||
|
|
74f8e744ac | ||
|
|
1c657036da | ||
|
|
2869bb3ef3 | ||
|
|
784e117a8a | ||
|
|
8c2ea052de | ||
|
|
0b6bbf6733 | ||
|
|
2312df3718 | ||
|
|
095dd73c52 | ||
|
|
ac6ac42860 | ||
|
|
c6ce888cc7 |
+4
-3
@@ -55,7 +55,7 @@ rust:nightly:
|
|||||||
- web
|
- web
|
||||||
|
|
||||||
flatpak:
|
flatpak:
|
||||||
image: registry.gitlab.com/alatiera/gnome-nightly-oci/rust-bundle:latest
|
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/rust_bundle:3.28
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- flatpak-builder --stop-at=hammond app org.gnome.Hammond.json
|
- flatpak-builder --stop-at=hammond app org.gnome.Hammond.json
|
||||||
@@ -125,7 +125,7 @@ rustfmt:
|
|||||||
script:
|
script:
|
||||||
- rustc -Vv && cargo -Vv
|
- rustc -Vv && cargo -Vv
|
||||||
- cargo fmt --version
|
- cargo fmt --version
|
||||||
- cargo fmt --all -- --write-mode=diff
|
- cargo fmt --all -- --check
|
||||||
|
|
||||||
# Configure and run clippy on nightly
|
# Configure and run clippy on nightly
|
||||||
# Only fails on errors atm.
|
# Only fails on errors atm.
|
||||||
@@ -134,10 +134,11 @@ clippy:
|
|||||||
stage: lint
|
stage: lint
|
||||||
variables:
|
variables:
|
||||||
RUSTFLAGS: "--cfg rayon_unstable"
|
RUSTFLAGS: "--cfg rayon_unstable"
|
||||||
|
CARGO_HOME: ".cargo_cache"
|
||||||
script:
|
script:
|
||||||
- rustc --version && cargo --version
|
- rustc --version && cargo --version
|
||||||
- cargo clippy --version
|
- cargo clippy --version
|
||||||
# Force regeneration of gresources regardless of artifacts chage
|
# Force regeneration of gresources regardless of artifacts chage
|
||||||
- cd hammond-gtk/resources/ && glib-compile-resources --generate resources.xml && cd ../../
|
- cd hammond-gtk/resources/ && glib-compile-resources --generate resources.xml && cd ../../
|
||||||
- cargo clippy --all
|
- cargo clippy --all
|
||||||
<<: *cargo_cache
|
<<: *cargo_cache
|
||||||
|
|||||||
@@ -6,10 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added:
|
### Added:
|
||||||
|
- Keyboard Shortcuts and a Shortcuts dialog were implemented. (ZanderBrown) [!33](https://gitlab.gnome.org/World/hammond/merge_requests/33)
|
||||||
|
|
||||||
### Changed:
|
### Changed:
|
||||||
|
- The `FileChooser` of the OPML import was changed to use the `FileChooserNative` widget/API. (ZanderBrown) [!33](https://gitlab.gnome.org/World/hammond/merge_requests/33)
|
||||||
|
- The `EpisdeWidget` was refactored. [!38](https://gitlab.gnome.org/World/hammond/merge_requests/38)
|
||||||
|
- `EpisdeWidget`'s progressbar was changed to be non-blocking and should feel way more responsive now. 9b0ac5b83dadecdff51cd398293afdf0d5276012
|
||||||
|
|
||||||
### Fixed:
|
### Fixed:
|
||||||
|
- Fixed a bug whre the about dialog would be unclosable. (ZanderBrown) [!37](https://gitlab.gnome.org/World/hammond/merge_requests/37)
|
||||||
|
|
||||||
### Removed:
|
### Removed:
|
||||||
|
|
||||||
|
## [0.3.4] - 2018-05-20
|
||||||
|
### Fixed:
|
||||||
|
- Flatpak can now access the Home folder. This fixes the OPML import feature from
|
||||||
|
not being able to access any file.
|
||||||
|
|
||||||
## [0.3.3] - 2018-05-19
|
## [0.3.3] - 2018-05-19
|
||||||
### Added:
|
### Added:
|
||||||
- Initial functionality for importing shows from an OPML file was implemented.
|
- Initial functionality for importing shows from an OPML file was implemented.
|
||||||
|
|||||||
Generated
+179
-148
@@ -17,7 +17,7 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.6 (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)",
|
"tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -53,7 +53,7 @@ dependencies = [
|
|||||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -62,30 +62,31 @@ name = "atty"
|
|||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.7"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace-sys 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace-sys"
|
name = "backtrace-sys"
|
||||||
version = "0.1.16"
|
version = "0.1.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -119,7 +120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "0.4.7"
|
version = "0.4.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -140,7 +141,7 @@ dependencies = [
|
|||||||
"cairo-sys-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cairo-sys-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -148,7 +149,7 @@ name = "cairo-sys-rs"
|
|||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -188,17 +189,25 @@ dependencies = [
|
|||||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cloudabi"
|
||||||
|
version = "0.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys 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.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -206,7 +215,7 @@ name = "core-foundation-sys"
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -232,9 +241,9 @@ dependencies = [
|
|||||||
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itertools-num 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools-num 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"simplelog 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"simplelog 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -262,12 +271,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-epoch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -288,19 +297,6 @@ dependencies = [
|
|||||||
"crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-epoch"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"memoffset 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -309,7 +305,7 @@ dependencies = [
|
|||||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -323,7 +319,7 @@ dependencies = [
|
|||||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -429,7 +425,7 @@ name = "error-chain"
|
|||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -437,7 +433,7 @@ name = "failure"
|
|||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -515,7 +511,7 @@ dependencies = [
|
|||||||
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pango 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pango 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -530,7 +526,7 @@ dependencies = [
|
|||||||
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -542,7 +538,7 @@ dependencies = [
|
|||||||
"gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -557,7 +553,7 @@ dependencies = [
|
|||||||
"gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pango-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pango-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -572,8 +568,8 @@ dependencies = [
|
|||||||
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -584,7 +580,7 @@ dependencies = [
|
|||||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -596,8 +592,8 @@ dependencies = [
|
|||||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -606,7 +602,7 @@ version = "0.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -622,7 +618,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -645,8 +641,8 @@ dependencies = [
|
|||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gtk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gtk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pango 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pango 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -663,7 +659,7 @@ dependencies = [
|
|||||||
"gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pango-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pango-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -683,13 +679,13 @@ dependencies = [
|
|||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rfc822_sanitizer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rfc822_sanitizer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -723,7 +719,7 @@ name = "hammond-gtk"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam-channel 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-channel 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gdk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gdk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -735,7 +731,7 @@ dependencies = [
|
|||||||
"hammond-downloader 0.1.0",
|
"hammond-downloader 0.1.0",
|
||||||
"html2pango 0.1.0 (git+https://gitlab.gnome.org/World/html2pango)",
|
"html2pango 0.1.0 (git+https://gitlab.gnome.org/World/html2pango)",
|
||||||
"humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"loggerv 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"loggerv 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -744,8 +740,7 @@ dependencies = [
|
|||||||
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"send-cell 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"send-cell 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -754,14 +749,14 @@ name = "handlebars"
|
|||||||
version = "0.31.0"
|
version = "0.31.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -772,7 +767,7 @@ dependencies = [
|
|||||||
"ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"linkify 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"linkify 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -788,7 +783,7 @@ dependencies = [
|
|||||||
"markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 0.13.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -807,7 +802,7 @@ version = "0.11.27"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -856,7 +851,7 @@ name = "iovec"
|
|||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -902,7 +897,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -912,7 +907,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.40"
|
version = "0.2.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -985,9 +980,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1003,14 +998,9 @@ name = "memchr"
|
|||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memoffset"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -1082,7 +1072,7 @@ dependencies = [
|
|||||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"iovec 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)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miow 0.2.1 (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.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1107,7 +1097,7 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 0.2.11 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"schannel 0.1.12 (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 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1121,7 +1111,7 @@ version = "0.2.32"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1156,7 +1146,7 @@ name = "num_cpus"
|
|||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1171,18 +1161,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"foreign-types 0.3.2 (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 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-sys 0.9.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.30"
|
version = "0.9.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -1204,7 +1194,7 @@ dependencies = [
|
|||||||
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pango-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pango-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1216,13 +1206,13 @@ dependencies = [
|
|||||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.4.8"
|
version = "0.5.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1234,7 +1224,7 @@ name = "parking_lot_core"
|
|||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1330,9 +1320,17 @@ dependencies = [
|
|||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-error"
|
name = "quick-error"
|
||||||
version = "1.2.1"
|
version = "1.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1366,6 +1364,14 @@ dependencies = [
|
|||||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "r2d2"
|
name = "r2d2"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
@@ -1382,7 +1388,7 @@ version = "0.3.22"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1392,10 +1398,27 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@@ -1411,8 +1434,8 @@ version = "1.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -1428,7 +1451,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.1.37"
|
version = "0.1.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1436,7 +1459,7 @@ name = "redox_termios"
|
|||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1500,7 +1523,7 @@ name = "reqwest"
|
|||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1509,8 +1532,8 @@ dependencies = [
|
|||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1554,7 +1577,7 @@ name = "schannel"
|
|||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1583,7 +1606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"security-framework-sys 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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1593,7 +1616,7 @@ version = "0.1.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys 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.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1603,27 +1626,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.57"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.57"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 0.13.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.17"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1633,7 +1656,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1683,10 +1706,10 @@ version = "0.7.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"precomputed-hash 0.1.1 (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.57 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"string_cache_shared 0.3.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)",
|
||||||
]
|
]
|
||||||
@@ -1735,7 +1758,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "0.13.10"
|
version = "0.13.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1743,6 +1766,16 @@ dependencies = [
|
|||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "synom"
|
name = "synom"
|
||||||
version = "0.11.3"
|
version = "0.11.3"
|
||||||
@@ -1765,11 +1798,6 @@ name = "take"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "take_mut"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempdir"
|
name = "tempdir"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@@ -1803,8 +1831,8 @@ name = "termion"
|
|||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1813,7 +1841,7 @@ name = "textwrap"
|
|||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1826,7 +1854,7 @@ name = "thread_local"
|
|||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1835,8 +1863,8 @@ name = "time"
|
|||||||
version = "0.1.40"
|
version = "0.1.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1862,7 +1890,7 @@ name = "tokio-core"
|
|||||||
version = "0.1.17"
|
version = "0.1.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1898,7 +1926,7 @@ name = "tokio-io"
|
|||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -1946,7 +1974,7 @@ name = "tokio-tcp"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1992,7 +2020,7 @@ name = "tokio-udp"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2041,7 +2069,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2185,14 +2213,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||||
"checksum atk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8dc233521f7bffd3042c31082ea71bd08820abf44bac938fb36591e20f76f39"
|
"checksum atk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8dc233521f7bffd3042c31082ea71bd08820abf44bac938fb36591e20f76f39"
|
||||||
"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
|
"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
|
||||||
"checksum backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea58cd16fd6c9d120b5bcb01d63883ae4cc7ba2aed35c1841b862a3c7ef6639"
|
"checksum backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbdd17cd962b570302f5297aea8648d5923e22e555c2ed2d8b2e34eca646bf6d"
|
||||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
"checksum backtrace-sys 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5fd343a2466c4603f76f38de264bc0526cffc7fa38ba52fb9f13237eccc1ced2"
|
||||||
"checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007"
|
"checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007"
|
||||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||||
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
|
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
|
||||||
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
||||||
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
|
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
|
||||||
"checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59"
|
"checksum bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd32989a66957d3f0cba6588f15d4281a733f4e9ffc43fcd2385f57d3bf99ff"
|
||||||
"checksum c_vec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11f56b93adbca81a4ed1bb654070013b496a9b0b259a296281f4be24af84debd"
|
"checksum c_vec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11f56b93adbca81a4ed1bb654070013b496a9b0b259a296281f4be24af84debd"
|
||||||
"checksum cairo-rs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a110f269c2fd382df5fe8bd46dfa5f1b83608aa717fecb6e7a28c08c202f0e13"
|
"checksum cairo-rs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a110f269c2fd382df5fe8bd46dfa5f1b83608aa717fecb6e7a28c08c202f0e13"
|
||||||
"checksum cairo-sys-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0395175ecba60accac076a02c31d143b9dcd9d5eb5316d7163a3273803b765c7"
|
"checksum cairo-sys-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0395175ecba60accac076a02c31d143b9dcd9d5eb5316d7163a3273803b765c7"
|
||||||
@@ -2201,16 +2229,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
|
"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
|
||||||
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
|
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
|
||||||
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
|
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
|
||||||
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67"
|
"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67"
|
||||||
"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d"
|
"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d"
|
||||||
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||||
"checksum criterion 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f11151e2961d0483e5eb7a2ede5ed8071a460d04d2b7c89e8257aa5502b0e0b"
|
"checksum criterion 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f11151e2961d0483e5eb7a2ede5ed8071a460d04d2b7c89e8257aa5502b0e0b"
|
||||||
"checksum criterion-plot 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f7f7c88a8d341dd9fd9e31a72ca2ca24428db79afb491852873b2c784e037e6"
|
"checksum criterion-plot 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f7f7c88a8d341dd9fd9e31a72ca2ca24428db79afb491852873b2c784e037e6"
|
||||||
"checksum criterion-stats 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd48feb0253b2968ff3085e7f3fba6738c9ff859f420a2fb81a48986eb66da36"
|
"checksum criterion-stats 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd48feb0253b2968ff3085e7f3fba6738c9ff859f420a2fb81a48986eb66da36"
|
||||||
"checksum crossbeam-channel 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7b07a3084d8718d95338443d5a46aab38ce16d5f991d4027a0906b369f70a3"
|
"checksum crossbeam-channel 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "862becd07e73da5746de6d9b3ba055c9bb8b10afd0d2b51155a6e30d81cd20b3"
|
||||||
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
||||||
"checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7"
|
"checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7"
|
||||||
"checksum crossbeam-epoch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9898f21d6d647793e163c804944941fb19aecd1f4a1a4c254bbb0bee15ccdea5"
|
|
||||||
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
||||||
"checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81"
|
"checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81"
|
||||||
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
||||||
@@ -2262,9 +2290,9 @@ 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 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 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 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 lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
|
||||||
"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
|
"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
|
||||||
"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
|
"checksum libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)" = "ac8ebf8343a981e2fa97042b14768f02ed3e1d602eac06cae6166df3c8ced206"
|
||||||
"checksum libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1a429b86418868c7ea91ee50e9170683f47fd9d94f5375438ec86ec3adb74e8e"
|
"checksum libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1a429b86418868c7ea91ee50e9170683f47fd9d94f5375438ec86ec3adb74e8e"
|
||||||
"checksum libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9eb7b8e152b6a01be6a4a2917248381875758250dc3df5d46caf9250341dda"
|
"checksum libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9eb7b8e152b6a01be6a4a2917248381875758250dc3df5d46caf9250341dda"
|
||||||
"checksum linkify 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ce9439c6f4a1092dc1861272bef01034891da39f13aa1cdcf40ca3e4081de5f"
|
"checksum linkify 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ce9439c6f4a1092dc1861272bef01034891da39f13aa1cdcf40ca3e4081de5f"
|
||||||
@@ -2276,7 +2304,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475"
|
"checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475"
|
||||||
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
|
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
|
||||||
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
||||||
"checksum memoffset 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e163e5baece1a039e71e75b074de17a9b4114982aa109921fc20253bdf91a53c"
|
|
||||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||||
"checksum migrations_internals 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54b8f3128f95b1e5b5f5d5d7ce2156b306b9d11dd50e23b594f25247e30ca83a"
|
"checksum migrations_internals 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54b8f3128f95b1e5b5f5d5d7ce2156b306b9d11dd50e23b594f25247e30ca83a"
|
||||||
"checksum migrations_macros 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a616c2538e1f09bf402efae6feb73c2711bb137c794b797f3fb8b3df84275d4b"
|
"checksum migrations_macros 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a616c2538e1f09bf402efae6feb73c2711bb137c794b797f3fb8b3df84275d4b"
|
||||||
@@ -2295,11 +2322,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
||||||
"checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113"
|
"checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113"
|
||||||
"checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985"
|
"checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985"
|
||||||
"checksum openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)" = "73ae718c3562989cd3a0a5c26610feca02f8116822f6f195e6cf4887481e57f5"
|
"checksum openssl-sys 0.9.31 (registry+https://github.com/rust-lang/crates.io-index)" = "a4d6a27d108b29befe1822d40e2e22f85518dac59acbf7f30fdc532f48fd0a77"
|
||||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||||
"checksum pango 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45374801e224373c3c0393cd48073c81093494c8735721e81d1dbaa4096b2767"
|
"checksum pango 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45374801e224373c3c0393cd48073c81093494c8735721e81d1dbaa4096b2767"
|
||||||
"checksum pango-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94039b3921a4af4058a3e4335e5d15099101f298a92f5afc40bab3a3027594a1"
|
"checksum pango-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94039b3921a4af4058a3e4335e5d15099101f298a92f5afc40bab3a3027594a1"
|
||||||
"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
|
"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac"
|
||||||
"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
|
"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
|
||||||
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||||
"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc"
|
"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc"
|
||||||
@@ -2313,18 +2340,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
|
"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
|
||||||
"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0"
|
"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0"
|
||||||
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
|
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
|
||||||
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
|
"checksum proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1fa93823f53cfd0f5ac117b189aed6cfdfb2cfc0a9d82e956dd7927595ed7d46"
|
||||||
|
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||||
"checksum quick-xml 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b14c27e04216596a49f2b82398a24f67ed9f131a5c0e0235496ea446bdacfb12"
|
"checksum quick-xml 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b14c27e04216596a49f2b82398a24f67ed9f131a5c0e0235496ea446bdacfb12"
|
||||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||||
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
|
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
|
||||||
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
||||||
|
"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
|
||||||
"checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46"
|
"checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46"
|
||||||
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
||||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||||
|
"checksum rand 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a89abf8d34faf9783692392dca7bcdc6e82fa84eca86ccb6301ec87f3497185"
|
||||||
|
"checksum rand_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7a5f27547c49e5ccf8a586db3f3782fd93cf849780b21853b9d981db203302"
|
||||||
"checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
|
"checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
|
||||||
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
|
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
|
||||||
"checksum rayon-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea70dae42033c388536c7e9bdca084a14d75659c12e25fc105e7552464a87c4a"
|
"checksum rayon-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea70dae42033c388536c7e9bdca084a14d75659c12e25fc105e7552464a87c4a"
|
||||||
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
"checksum redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "0a12d51a5b5fd700e6c757f15877685bfa04fd7eb60c108f01d045cafa0073c2"
|
||||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||||
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
|
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
|
||||||
"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
|
"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
|
||||||
@@ -2344,9 +2375,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332"
|
"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 security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead"
|
||||||
"checksum send-cell 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fecc1ff30726db72867bc644a57a8914e7cb023b396489873f78e11f9c96b280"
|
"checksum send-cell 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fecc1ff30726db72867bc644a57a8914e7cb023b396489873f78e11f9c96b280"
|
||||||
"checksum serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)" = "9478f147957b713a156ce5e4529d77275bbcfddc29563b794939b36230df8ca8"
|
"checksum serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4a07014dd9a6845448a9e62f6f27595847f09828caabf1b1d50bb6755fa4d2"
|
||||||
"checksum serde_derive 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)" = "1bdba9c305f1aeff7e83e2ff0685a141780de943cee66bdd89b63913b2b69c86"
|
"checksum serde_derive 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)" = "d68003d21ef20c5c48354638c2e5c0d4ce4a056fdbf973839e0e86054eae7794"
|
||||||
"checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1"
|
"checksum serde_json 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ee382a792fabc5d720630aeafe1a4c69abe3d32aaaa5dbba6762fd8246d1bbe3"
|
||||||
"checksum serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e703cef904312097cfceab9ce131ff6bbe09e8c964a0703345a5f49238757bc1"
|
"checksum serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e703cef904312097cfceab9ce131ff6bbe09e8c964a0703345a5f49238757bc1"
|
||||||
"checksum simplelog 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9cc12b39fdf4c9a07f88bffac2d628f0118ed5ac077a4b0feece61fadf1429e5"
|
"checksum simplelog 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9cc12b39fdf4c9a07f88bffac2d628f0118ed5ac077a4b0feece61fadf1429e5"
|
||||||
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
|
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
|
||||||
@@ -2361,11 +2392,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||||
"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5"
|
"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5"
|
||||||
"checksum syn 0.13.10 (registry+https://github.com/rust-lang/crates.io-index)" = "77961dcdac942fa8bc033c16f3a790b311c8a27d00811b878ebd8cf9b7ba39d5"
|
"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
|
||||||
|
"checksum syn 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6dfd71b2be5a58ee30a6f8ea355ba8290d397131c00dfa55c3d34e6e13db5101"
|
||||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||||
"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd"
|
"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd"
|
||||||
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
|
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
|
||||||
"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
|
|
||||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||||
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
|
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
|
||||||
"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
|
"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
|
||||||
@@ -2393,7 +2424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a"
|
"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a"
|
||||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||||
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
|
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
|
||||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
|
"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
|
||||||
|
|||||||
@@ -4,12 +4,11 @@
|
|||||||
|
|
||||||
## Priorities
|
## Priorities
|
||||||
|
|
||||||
- [ ] Unplayed Only and Downloaded only view.
|
|
||||||
- [ ] OPML import/export // Probably need to create a crate.
|
- [ ] OPML import/export // Probably need to create a crate.
|
||||||
|
|
||||||
## Second
|
## Second
|
||||||
|
|
||||||
- [ ] Make use of file metadas, [This](https://github.com/GuillaumeGomez/audio-video-metadata) might be helpfull.
|
- [ ] Make use of file metadas?, [This](https://github.com/GuillaumeGomez/audio-video-metadata) might be helpfull.
|
||||||
- [ ] Episode queue
|
- [ ] Episode queue
|
||||||
- [ ] Embedded player
|
- [ ] Embedded player
|
||||||
- [ ] MPRIS integration
|
- [ ] MPRIS integration
|
||||||
@@ -19,14 +18,8 @@
|
|||||||
|
|
||||||
- [ ] Download Queue
|
- [ ] Download Queue
|
||||||
- [ ] Ability to Stream content on demand
|
- [ ] Ability to Stream content on demand
|
||||||
- [ ] soundcloud and itunes feeds // [This](http://getrssfeed.com) seems intresting.
|
- [ ] rss feeds from soundcloud urls? // [This](http://getrssfeed.com) seems intresting.
|
||||||
- [ ] Integrate with Itunes API for various crap?
|
- [ ] Integrate with Itunes API for various crap?
|
||||||
- [ ] YoutubeFeeds?
|
- [ ] YoutubeFeeds?
|
||||||
|
|
||||||
## Rest Tasks
|
## Rest Tasks
|
||||||
|
|
||||||
**Would be nice:**
|
|
||||||
|
|
||||||
- [ ] Make Podcast cover fetchng and loading not block the execution of the program at startup.
|
|
||||||
- [ ] Lazy evaluate episode loading based on the show_widget's scrolling.
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,14 +28,14 @@ failure_derive = "0.1.1"
|
|||||||
|
|
||||||
[dependencies.diesel]
|
[dependencies.diesel]
|
||||||
features = ["sqlite", "r2d2"]
|
features = ["sqlite", "r2d2"]
|
||||||
version = "1.2.2"
|
version = "= 1.2.2"
|
||||||
|
|
||||||
[dependencies.diesel_migrations]
|
[dependencies.diesel_migrations]
|
||||||
features = ["sqlite"]
|
features = ["sqlite"]
|
||||||
version = "1.2.0"
|
version = "= 1.2.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.4.2"
|
rand = "0.5.0"
|
||||||
tempdir = "0.3.7"
|
tempdir = "0.3.7"
|
||||||
criterion = "0.2.3"
|
criterion = "0.2.3"
|
||||||
pretty_assertions = "0.5.1"
|
pretty_assertions = "0.5.1"
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
//! Database Setup. This is only public to help with some unit tests.
|
//! Database Setup. This is only public to help with some unit tests.
|
||||||
|
// Diesel embed_migrations! triggers the lint
|
||||||
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use diesel::r2d2;
|
use diesel::r2d2;
|
||||||
|
|||||||
@@ -129,6 +129,18 @@ pub fn get_episode_local_uri_from_id(ep_id: i32) -> Result<Option<String>, DataE
|
|||||||
.map_err(From::from)
|
.map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_episode_description(rowid_: i32) -> Result<Option<String>, DataError> {
|
||||||
|
use schema::episode::dsl::*;
|
||||||
|
let db = connection();
|
||||||
|
let con = db.get()?;
|
||||||
|
|
||||||
|
episode
|
||||||
|
.filter(rowid.eq(rowid_))
|
||||||
|
.select(description)
|
||||||
|
.get_result::<Option<String>>(&con)
|
||||||
|
.map_err(From::from)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_episodes_widgets_filter_limit(
|
pub fn get_episodes_widgets_filter_limit(
|
||||||
filter_ids: &[i32],
|
filter_ids: &[i32],
|
||||||
limit: u32,
|
limit: u32,
|
||||||
@@ -360,7 +372,18 @@ pub(crate) fn episode_exists(title_: &str, podcast_id_: i32) -> Result<bool, Dat
|
|||||||
.map_err(From::from)
|
.map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the `episode table contains any rows
|
pub fn episode_had_description(rowid_: i32) -> Result<bool, DataError> {
|
||||||
|
use schema::episode::dsl::*;
|
||||||
|
|
||||||
|
let db = connection();
|
||||||
|
let con = db.get()?;
|
||||||
|
|
||||||
|
select(exists(episode.filter(rowid.eq(rowid_))))
|
||||||
|
.get_result(&con)
|
||||||
|
.map_err(From::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if the `episode` table contains any rows
|
||||||
///
|
///
|
||||||
/// Return true if `episode` table is populated.
|
/// Return true if `episode` table is populated.
|
||||||
pub fn is_episodes_populated() -> Result<bool, DataError> {
|
pub fn is_episodes_populated() -> Result<bool, DataError> {
|
||||||
|
|||||||
@@ -174,7 +174,8 @@ mod tests {
|
|||||||
fn test_complete_index() {
|
fn test_complete_index() {
|
||||||
truncate_db().unwrap();
|
truncate_db().unwrap();
|
||||||
|
|
||||||
let feeds: Vec<_> = URLS.iter()
|
let feeds: Vec<_> = URLS
|
||||||
|
.iter()
|
||||||
.map(|&(path, url)| {
|
.map(|&(path, url)| {
|
||||||
// Create and insert a Source into db
|
// Create and insert a Source into db
|
||||||
let s = Source::from_url(url).unwrap();
|
let s = Source::from_url(url).unwrap();
|
||||||
|
|||||||
@@ -101,17 +101,23 @@ impl Index<()> for NewEpisode {
|
|||||||
|
|
||||||
impl PartialEq<EpisodeMinimal> for NewEpisode {
|
impl PartialEq<EpisodeMinimal> for NewEpisode {
|
||||||
fn eq(&self, other: &EpisodeMinimal) -> bool {
|
fn eq(&self, other: &EpisodeMinimal) -> bool {
|
||||||
(self.title() == other.title()) && (self.uri() == other.uri())
|
(self.title() == other.title())
|
||||||
&& (self.duration() == other.duration()) && (self.epoch() == other.epoch())
|
&& (self.uri() == other.uri())
|
||||||
&& (self.guid() == other.guid()) && (self.podcast_id() == other.podcast_id())
|
&& (self.duration() == other.duration())
|
||||||
|
&& (self.epoch() == other.epoch())
|
||||||
|
&& (self.guid() == other.guid())
|
||||||
|
&& (self.podcast_id() == other.podcast_id())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<Episode> for NewEpisode {
|
impl PartialEq<Episode> for NewEpisode {
|
||||||
fn eq(&self, other: &Episode) -> bool {
|
fn eq(&self, other: &Episode) -> bool {
|
||||||
(self.title() == other.title()) && (self.uri() == other.uri())
|
(self.title() == other.title())
|
||||||
&& (self.duration() == other.duration()) && (self.epoch() == other.epoch())
|
&& (self.uri() == other.uri())
|
||||||
&& (self.guid() == other.guid()) && (self.podcast_id() == other.podcast_id())
|
&& (self.duration() == other.duration())
|
||||||
|
&& (self.epoch() == other.epoch())
|
||||||
|
&& (self.guid() == other.guid())
|
||||||
|
&& (self.podcast_id() == other.podcast_id())
|
||||||
&& (self.description() == other.description())
|
&& (self.description() == other.description())
|
||||||
&& (self.length() == other.length())
|
&& (self.length() == other.length())
|
||||||
}
|
}
|
||||||
@@ -182,9 +188,12 @@ pub(crate) struct NewEpisodeMinimal {
|
|||||||
|
|
||||||
impl PartialEq<EpisodeMinimal> for NewEpisodeMinimal {
|
impl PartialEq<EpisodeMinimal> for NewEpisodeMinimal {
|
||||||
fn eq(&self, other: &EpisodeMinimal) -> bool {
|
fn eq(&self, other: &EpisodeMinimal) -> bool {
|
||||||
(self.title() == other.title()) && (self.uri() == other.uri())
|
(self.title() == other.title())
|
||||||
&& (self.duration() == other.duration()) && (self.epoch() == other.epoch())
|
&& (self.uri() == other.uri())
|
||||||
&& (self.guid() == other.guid()) && (self.podcast_id() == other.podcast_id())
|
&& (self.duration() == other.duration())
|
||||||
|
&& (self.epoch() == other.epoch())
|
||||||
|
&& (self.guid() == other.guid())
|
||||||
|
&& (self.podcast_id() == other.podcast_id())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ impl Index<()> for NewPodcast {
|
|||||||
|
|
||||||
impl PartialEq<Podcast> for NewPodcast {
|
impl PartialEq<Podcast> for NewPodcast {
|
||||||
fn eq(&self, other: &Podcast) -> bool {
|
fn eq(&self, other: &Podcast) -> bool {
|
||||||
(self.link() == other.link()) && (self.title() == other.title())
|
(self.link() == other.link())
|
||||||
|
&& (self.title() == other.title())
|
||||||
&& (self.image_uri() == other.image_uri())
|
&& (self.image_uri() == other.image_uri())
|
||||||
&& (self.description() == other.description())
|
&& (self.description() == other.description())
|
||||||
&& (self.source_id() == other.source_id())
|
&& (self.source_id() == other.source_id())
|
||||||
@@ -103,7 +104,8 @@ impl NewPodcast {
|
|||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
// Try to get the itunes img first
|
// Try to get the itunes img first
|
||||||
let itunes_img = chan.itunes_ext()
|
let itunes_img = chan
|
||||||
|
.itunes_ext()
|
||||||
.and_then(|s| s.image().map(|url| url.trim()))
|
.and_then(|s| s.image().map(|url| url.trim()))
|
||||||
.map(|s| s.to_owned());
|
.map(|s| s.to_owned());
|
||||||
// If itunes is None, try to get the channel.image from the rss spec
|
// If itunes is None, try to get the channel.image from the rss spec
|
||||||
|
|||||||
@@ -197,7 +197,8 @@ pub fn get_episode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache_image(pd: &PodcastCoverQuery) -> Result<String, DownloadError> {
|
pub fn cache_image(pd: &PodcastCoverQuery) -> Result<String, DownloadError> {
|
||||||
let url = pd.image_uri()
|
let url = pd
|
||||||
|
.image_uri()
|
||||||
.ok_or_else(|| DownloadError::NoImageLocation)?
|
.ok_or_else(|| DownloadError::NoImageLocation)?
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
@@ -215,7 +216,8 @@ pub fn cache_image(pd: &PodcastCoverQuery) -> Result<String, DownloadError> {
|
|||||||
// For some reason there is no .first() method so nth(0) is used
|
// For some reason there is no .first() method so nth(0) is used
|
||||||
let path = foo.nth(0).and_then(|x| x.ok());
|
let path = foo.nth(0).and_then(|x| x.ok());
|
||||||
if let Some(p) = path {
|
if let Some(p) = path {
|
||||||
return Ok(p.to_str()
|
return Ok(p
|
||||||
|
.to_str()
|
||||||
.ok_or_else(|| DownloadError::InvalidCachedImageLocation)?
|
.ok_or_else(|| DownloadError::InvalidCachedImageLocation)?
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ send-cell = "0.1.3"
|
|||||||
url = "1.7.0"
|
url = "1.7.0"
|
||||||
failure = "0.1.1"
|
failure = "0.1.1"
|
||||||
failure_derive = "0.1.1"
|
failure_derive = "0.1.1"
|
||||||
take_mut = "0.2.2"
|
|
||||||
regex = "1.0.0"
|
regex = "1.0.0"
|
||||||
reqwest = "0.8.5"
|
reqwest = "0.8.5"
|
||||||
serde_json = "1.0.17"
|
serde_json = "1.0.17"
|
||||||
|
|||||||
@@ -41,37 +41,26 @@ Tobias Bernard
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox" id="info_container">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkLabel" id="title_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<child>
|
<property name="label" translatable="yes">Episode Title</property>
|
||||||
<object class="GtkLabel" id="title_label">
|
<property name="ellipsize">end</property>
|
||||||
<property name="visible">True</property>
|
<property name="width_chars">55</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="single_line_mode">True</property>
|
||||||
<property name="label" translatable="yes">Episode Title</property>
|
<property name="track_visited_links">False</property>
|
||||||
<property name="ellipsize">end</property>
|
<property name="lines">1</property>
|
||||||
<property name="width_chars">55</property>
|
<property name="xalign">0</property>
|
||||||
<property name="single_line_mode">True</property>
|
|
||||||
<property name="track_visited_links">False</property>
|
|
||||||
<property name="lines">1</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">False</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
@@ -213,23 +202,53 @@ Tobias Bernard
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkButtonBox" id="button_box">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="spacing">6</property>
|
<property name="layout_style">center</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="cancel_button">
|
<object class="GtkButton" id="desc_button">
|
||||||
<property name="label" translatable="yes">Cancel</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">False</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="no_show_all">True</property>
|
<property name="halign">center</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">view-paged-symbolic</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
<property name="non_homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="play_button">
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="no_show_all">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Play this episode</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">media-playback-start-symbolic</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="pack_type">end</property>
|
<property name="position">2</property>
|
||||||
<property name="position">0</property>
|
<property name="non_homogeneous">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -237,8 +256,8 @@ Tobias Bernard
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="no_show_all">True</property>
|
|
||||||
<property name="tooltip_text" translatable="yes">Download this episode</property>
|
<property name="tooltip_text" translatable="yes">Download this episode</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
<child>
|
<child>
|
||||||
@@ -252,24 +271,17 @@ Tobias Bernard
|
|||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="pack_type">end</property>
|
<property name="position">3</property>
|
||||||
<property name="position">2</property>
|
<property name="non_homogeneous">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="play_button">
|
<object class="GtkButton" id="cancel_button">
|
||||||
|
<property name="label" translatable="yes">Cancel</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="no_show_all">True</property>
|
<property name="halign">center</property>
|
||||||
<property name="tooltip_text" translatable="yes">Play this episode</property>
|
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="icon_name">media-playback-start-symbolic</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -282,7 +294,6 @@ Tobias Bernard
|
|||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="padding">6</property>
|
|
||||||
<property name="pack_type">end</property>
|
<property name="pack_type">end</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
|
|||||||
@@ -257,12 +257,12 @@ Tobias Bernard
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton" id="menu_toggle">
|
<object class="GtkMenuButton" id="menu_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">False</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="popover">menu_popover</property>
|
<property name="use_popover">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -281,125 +281,4 @@ Tobias Bernard
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkPopover" id="menu_popover">
|
</interface>
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="relative_to">menu_toggle</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_left">10</property>
|
|
||||||
<property name="margin_right">10</property>
|
|
||||||
<property name="margin_top">10</property>
|
|
||||||
<property name="margin_bottom">10</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="text" translatable="yes">Preferences</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton" id="update_button">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="text" translatable="yes">Check for new episodes</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton" id="import">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="text" translatable="yes">Import Shows</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton" id="export">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="text" translatable="yes">Export Shows</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSeparator">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton" id="about">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="text" translatable="yes">About</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">6</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="text" translatable="yes">Help</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">7</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="text" translatable="yes">Keyboard Shortcuts</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">8</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</interface>
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<object class="GtkShortcutsWindow" id="help_overlay">
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkShortcutsSection">
|
||||||
|
<property name="section-name">shortcuts</property>
|
||||||
|
<property name="max-height">12</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkShortcutsGroup">
|
||||||
|
<property name="title" translatable="yes">General</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkShortcutsShortcut">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="accelerator"><primary>r</property>
|
||||||
|
<property name="title" translatable="yes" context="shortcut window">Check for new episodes</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkShortcutsShortcut">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="accelerator"><primary>q</property>
|
||||||
|
<property name="title" translatable="yes" context="shortcut window">Quit the application</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<interface>
|
||||||
|
<!-- interface-requires gtk+ 3.0 -->
|
||||||
|
<menu id="menu">
|
||||||
|
<section>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">_Check for new episodes</attribute>
|
||||||
|
<attribute name="action">app.refresh</attribute>
|
||||||
|
<attribute name="accel"><primary>r</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">_Import Shows</attribute>
|
||||||
|
<attribute name="action">app.import</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">_Export Shows</attribute>
|
||||||
|
<attribute name="action">app.export</attribute>
|
||||||
|
</item>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">_Preferences</attribute>
|
||||||
|
<attribute name="action">app.preferences</attribute>
|
||||||
|
</item>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
|
||||||
|
<attribute name="action">win.show-help-overlay</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">_Help</attribute>
|
||||||
|
<attribute name="action">app.help</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">_About</attribute>
|
||||||
|
<attribute name="action">app.about</attribute>
|
||||||
|
</item>
|
||||||
|
</section>
|
||||||
|
</menu>
|
||||||
|
</interface>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
</screenshot>
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="0.3.3" date="2018-05-19"/>
|
<release version="0.3.4" date="2018-05-20"/>
|
||||||
</releases>
|
</releases>
|
||||||
<url type="homepage">https://gitlab.gnome.org/World/hammond</url>
|
<url type="homepage">https://gitlab.gnome.org/World/hammond</url>
|
||||||
<update_contact>jpetridis@gnome.org</update_contact>
|
<update_contact>jpetridis@gnome.org</update_contact>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<gresources>
|
<gresources>
|
||||||
<gresource prefix="/org/gnome/hammond/">
|
<gresource prefix="/org/gnome/Hammond/">
|
||||||
<file compressed="true" preprocess="xml-stripblanks">gtk/episode_widget.ui</file>
|
<file compressed="true" preprocess="xml-stripblanks">gtk/episode_widget.ui</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">gtk/show_widget.ui</file>
|
<file compressed="true" preprocess="xml-stripblanks">gtk/show_widget.ui</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">gtk/empty_view.ui</file>
|
<file compressed="true" preprocess="xml-stripblanks">gtk/empty_view.ui</file>
|
||||||
@@ -11,6 +11,8 @@
|
|||||||
<file compressed="true" preprocess="xml-stripblanks">gtk/shows_child.ui</file>
|
<file compressed="true" preprocess="xml-stripblanks">gtk/shows_child.ui</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">gtk/headerbar.ui</file>
|
<file compressed="true" preprocess="xml-stripblanks">gtk/headerbar.ui</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">gtk/inapp_notif.ui</file>
|
<file compressed="true" preprocess="xml-stripblanks">gtk/inapp_notif.ui</file>
|
||||||
|
<file compressed="true" preprocess="xml-stripblanks">gtk/menus.ui</file>
|
||||||
|
<file compressed="true" preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
||||||
<file compressed="true">gtk/style.css</file>
|
<file compressed="true">gtk/style.css</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
</gresources>
|
</gresources>
|
||||||
|
|||||||
+203
-130
@@ -1,24 +1,41 @@
|
|||||||
#![allow(new_without_default)]
|
#![allow(new_without_default)]
|
||||||
|
|
||||||
use gio::{ApplicationExt, ApplicationExtManual, ApplicationFlags, Settings, SettingsExt};
|
use gio::{
|
||||||
|
ActionMapExt, ApplicationExt, ApplicationExtManual, ApplicationFlags, Settings, SettingsExt,
|
||||||
|
SimpleAction, SimpleActionExt,
|
||||||
|
};
|
||||||
use glib;
|
use glib;
|
||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::SettingsExt as GtkSettingsExt;
|
use gtk::SettingsExt as GtkSettingsExt;
|
||||||
|
|
||||||
use hammond_data::Podcast;
|
use crossbeam_channel::{unbounded, Sender};
|
||||||
|
use hammond_data::{Podcast, dbqueries};
|
||||||
|
|
||||||
use appnotif::{InAppNotification, UndoState};
|
|
||||||
use headerbar::Header;
|
use headerbar::Header;
|
||||||
use settings::{self, WindowGeometry};
|
use settings::{self, WindowGeometry};
|
||||||
use stacks::{Content, PopulatedState};
|
use stacks::{Content, PopulatedState};
|
||||||
use utils;
|
use utils;
|
||||||
use widgets::{mark_all_notif, remove_show_notif};
|
use widgets::appnotif::{InAppNotification, UndoState};
|
||||||
|
use widgets::{about_dialog, mark_all_notif, remove_show_notif};
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Creates an action named $called in the action map $on with the handler $handle
|
||||||
|
macro_rules! action {
|
||||||
|
($on:expr, $called:expr, $handle:expr) => {{
|
||||||
|
// Create a stateless, parameterless action
|
||||||
|
let act = SimpleAction::new($called, None);
|
||||||
|
// Connect the handler
|
||||||
|
act.connect_activate($handle);
|
||||||
|
// Add it to the map
|
||||||
|
$on.add_action(&act);
|
||||||
|
// Return the action
|
||||||
|
act
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
RefreshAllViews,
|
RefreshAllViews,
|
||||||
@@ -36,17 +53,12 @@ pub enum Action {
|
|||||||
MarkAllPlayerNotification(Arc<Podcast>),
|
MarkAllPlayerNotification(Arc<Podcast>),
|
||||||
RemoveShow(Arc<Podcast>),
|
RemoveShow(Arc<Podcast>),
|
||||||
ErrorNotification(String),
|
ErrorNotification(String),
|
||||||
|
AboutWidget(i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
app_instance: gtk::Application,
|
app_instance: gtk::Application,
|
||||||
window: gtk::Window,
|
|
||||||
overlay: gtk::Overlay,
|
|
||||||
header: Rc<Header>,
|
|
||||||
content: Rc<Content>,
|
|
||||||
receiver: Receiver<Action>,
|
|
||||||
sender: Sender<Action>,
|
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,62 +75,150 @@ impl App {
|
|||||||
let cleanup_date = settings::get_cleanup_date(&settings);
|
let cleanup_date = settings::get_cleanup_date(&settings);
|
||||||
utils::cleanup(cleanup_date);
|
utils::cleanup(cleanup_date);
|
||||||
|
|
||||||
// Create the main window
|
application.connect_startup(clone!(settings => move |app| {
|
||||||
let window = gtk::Window::new(gtk::WindowType::Toplevel);
|
let (sender, receiver) = unbounded();
|
||||||
window.set_title("Hammond");
|
|
||||||
|
|
||||||
window.connect_delete_event(clone!(application, settings, window => move |_, _| {
|
App::setup_gactions(&app, &sender);
|
||||||
WindowGeometry::from_window(&window).write(&settings);
|
|
||||||
application.quit();
|
app.connect_activate(clone!(sender, settings => move |app| {
|
||||||
Inhibit(false)
|
// Get the current window (if any)
|
||||||
|
if let Some(window) = app.get_active_window() {
|
||||||
|
// Already open, just raise the window
|
||||||
|
window.present();
|
||||||
|
} else {
|
||||||
|
// Time to open one!
|
||||||
|
// Create the main window
|
||||||
|
let window = gtk::ApplicationWindow::new(&app);
|
||||||
|
window.set_title("Hammond");
|
||||||
|
|
||||||
|
window.connect_delete_event(clone!(app, settings => move |window, _| {
|
||||||
|
WindowGeometry::from_window(&window).write(&settings);
|
||||||
|
app.quit();
|
||||||
|
Inhibit(false)
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Create a content instance
|
||||||
|
let content =
|
||||||
|
Rc::new(Content::new(sender.clone()).expect(
|
||||||
|
"Content Initialization failed."));
|
||||||
|
|
||||||
|
// Create the headerbar
|
||||||
|
let header = Rc::new(Header::new(&content, &window, &sender));
|
||||||
|
|
||||||
|
action!(window, "menu", clone!(header => move |_, _| {
|
||||||
|
header.open_menu();
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Add the content main stack to the overlay.
|
||||||
|
let overlay = gtk::Overlay::new();
|
||||||
|
overlay.add(&content.get_stack());
|
||||||
|
|
||||||
|
// Add the overlay to the main window
|
||||||
|
window.add(&overlay);
|
||||||
|
|
||||||
|
WindowGeometry::from_settings(&settings).apply(&window);
|
||||||
|
|
||||||
|
App::setup_timed_callbacks(&sender, &settings);
|
||||||
|
|
||||||
|
window.show_all();
|
||||||
|
window.activate();
|
||||||
|
|
||||||
|
gtk::timeout_add(50, clone!(sender, receiver => move || {
|
||||||
|
// Uses receiver, content, header, sender, overlay
|
||||||
|
match receiver.try_recv() {
|
||||||
|
Ok(Action::RefreshAllViews) => content.update(),
|
||||||
|
Ok(Action::RefreshShowsView) => content.update_shows_view(),
|
||||||
|
Ok(Action::RefreshWidgetIfSame(id)) =>
|
||||||
|
content.update_widget_if_same(id),
|
||||||
|
Ok(Action::RefreshEpisodesView) => content.update_home(),
|
||||||
|
Ok(Action::RefreshEpisodesViewBGR) =>
|
||||||
|
content.update_home_if_background(),
|
||||||
|
Ok(Action::ReplaceWidget(pd)) => {
|
||||||
|
let shows = content.get_shows();
|
||||||
|
let mut pop = shows.borrow().populated();
|
||||||
|
pop.borrow_mut()
|
||||||
|
.replace_widget(pd.clone())
|
||||||
|
.map_err(|err| error!("Failed to update ShowWidget: {}", err))
|
||||||
|
.map_err(|_|
|
||||||
|
error!("Failed ot update ShowWidget {}", pd.title()))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
Ok(Action::ShowWidgetAnimated) => {
|
||||||
|
let shows = content.get_shows();
|
||||||
|
let mut pop = shows.borrow().populated();
|
||||||
|
pop.borrow_mut().switch_visible(
|
||||||
|
PopulatedState::Widget,
|
||||||
|
gtk::StackTransitionType::SlideLeft,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(Action::ShowShowsAnimated) => {
|
||||||
|
let shows = content.get_shows();
|
||||||
|
let mut pop = shows.borrow().populated();
|
||||||
|
pop.borrow_mut()
|
||||||
|
.switch_visible(PopulatedState::View,
|
||||||
|
gtk::StackTransitionType::SlideRight);
|
||||||
|
}
|
||||||
|
Ok(Action::HeaderBarShowTile(title)) =>
|
||||||
|
header.switch_to_back(&title),
|
||||||
|
Ok(Action::HeaderBarNormal) => header.switch_to_normal(),
|
||||||
|
Ok(Action::HeaderBarShowUpdateIndicator) =>
|
||||||
|
header.show_update_notification(),
|
||||||
|
Ok(Action::HeaderBarHideUpdateIndicator) =>
|
||||||
|
header.hide_update_notification(),
|
||||||
|
Ok(Action::MarkAllPlayerNotification(pd)) => {
|
||||||
|
let notif = mark_all_notif(pd, &sender);
|
||||||
|
notif.show(&overlay);
|
||||||
|
}
|
||||||
|
Ok(Action::RemoveShow(pd)) => {
|
||||||
|
let notif = remove_show_notif(pd, sender.clone());
|
||||||
|
notif.show(&overlay);
|
||||||
|
}
|
||||||
|
Ok(Action::ErrorNotification(err)) => {
|
||||||
|
error!("An error notification was triggered: {}", err);
|
||||||
|
let callback = || glib::Continue(false);
|
||||||
|
let notif = InAppNotification::new(&err, callback,
|
||||||
|
|| {}, UndoState::Hidden);
|
||||||
|
notif.show(&overlay);
|
||||||
|
}
|
||||||
|
Ok(Action::AboutWidget(rowid)) => {
|
||||||
|
if let Ok(d) = dbqueries::get_episode_description(rowid) {
|
||||||
|
if let Some(_desc) = d {
|
||||||
|
let _stack = content.get_visible_stack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
Continue(true)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let (sender, receiver) = channel();
|
|
||||||
|
|
||||||
// Create a content instance
|
|
||||||
let content =
|
|
||||||
Rc::new(Content::new(sender.clone()).expect("Content Initialization failed."));
|
|
||||||
|
|
||||||
// Create the headerbar
|
|
||||||
let header = Rc::new(Header::new(&content, &window, &sender));
|
|
||||||
|
|
||||||
// Add the content main stack to the overlay.
|
|
||||||
let overlay = gtk::Overlay::new();
|
|
||||||
overlay.add(&content.get_stack());
|
|
||||||
|
|
||||||
// Add the overlay to the main window
|
|
||||||
window.add(&overlay);
|
|
||||||
|
|
||||||
App {
|
App {
|
||||||
app_instance: application,
|
app_instance: application,
|
||||||
window,
|
|
||||||
overlay,
|
|
||||||
header,
|
|
||||||
content,
|
|
||||||
receiver,
|
|
||||||
sender,
|
|
||||||
settings,
|
settings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_timed_callbacks(&self) {
|
fn setup_timed_callbacks(sender: &Sender<Action>, settings: &Settings) {
|
||||||
self.setup_dark_theme();
|
App::setup_dark_theme(settings);
|
||||||
self.setup_refresh_on_startup();
|
App::setup_refresh_on_startup(&sender, settings);
|
||||||
self.setup_auto_refresh();
|
App::setup_auto_refresh(&sender, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_dark_theme(&self) {
|
fn setup_dark_theme(settings: &Settings) {
|
||||||
let settings = gtk::Settings::get_default().unwrap();
|
let gtk_settings = gtk::Settings::get_default().unwrap();
|
||||||
let enabled = self.settings.get_boolean("dark-theme");
|
let enabled = settings.get_boolean("dark-theme");
|
||||||
|
|
||||||
settings.set_property_gtk_application_prefer_dark_theme(enabled);
|
gtk_settings.set_property_gtk_application_prefer_dark_theme(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_refresh_on_startup(&self) {
|
fn setup_refresh_on_startup(sender: &Sender<Action>, settings: &Settings) {
|
||||||
// Update the feeds right after the Application is initialized.
|
// Update the feeds right after the Application is initialized.
|
||||||
if self.settings.get_boolean("refresh-on-startup") {
|
let sender = sender.clone();
|
||||||
let sender = self.sender.clone();
|
if settings.get_boolean("refresh-on-startup") {
|
||||||
|
|
||||||
info!("Refresh on startup.");
|
info!("Refresh on startup.");
|
||||||
// The ui loads async, after initialization
|
// The ui loads async, after initialization
|
||||||
// so we need to delay this a bit so it won't block
|
// so we need to delay this a bit so it won't block
|
||||||
@@ -131,12 +231,12 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_auto_refresh(&self) {
|
fn setup_auto_refresh(sender: &Sender<Action>, settings: &Settings) {
|
||||||
let refresh_interval = settings::get_refresh_interval(&self.settings).num_seconds() as u32;
|
let refresh_interval = settings::get_refresh_interval(&settings).num_seconds() as u32;
|
||||||
let sender = self.sender.clone();
|
|
||||||
|
|
||||||
info!("Auto-refresh every {:?} seconds.", refresh_interval);
|
info!("Auto-refresh every {:?} seconds.", refresh_interval);
|
||||||
|
|
||||||
|
let sender = sender.clone();
|
||||||
gtk::timeout_add_seconds(refresh_interval, move || {
|
gtk::timeout_add_seconds(refresh_interval, move || {
|
||||||
let s: Option<Vec<_>> = None;
|
let s: Option<Vec<_>> = None;
|
||||||
utils::refresh(s, sender.clone());
|
utils::refresh(s, sender.clone());
|
||||||
@@ -145,82 +245,55 @@ impl App {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Define the `GAction`s.
|
||||||
|
///
|
||||||
|
/// Used in menus and the keyboard shortcuts dialog.
|
||||||
|
fn setup_gactions(app: >k::Application, sender: &Sender<Action>) {
|
||||||
|
// Create the `refresh` action.
|
||||||
|
//
|
||||||
|
// This will trigger a refresh of all the shows in the database.
|
||||||
|
action!(
|
||||||
|
app,
|
||||||
|
"refresh",
|
||||||
|
clone!(sender => move |_, _| {
|
||||||
|
gtk::idle_add(clone!(sender => move || {
|
||||||
|
let s: Option<Vec<_>> = None;
|
||||||
|
utils::refresh(s, sender.clone());
|
||||||
|
glib::Continue(false)
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
app.set_accels_for_action("app.refresh", &["<primary>r"]);
|
||||||
|
|
||||||
|
// Create the `OPML` import action
|
||||||
|
action!(
|
||||||
|
app,
|
||||||
|
"import",
|
||||||
|
clone!(sender, app => move |_, _| {
|
||||||
|
let window = app.get_active_window().expect("Failed to get active window");
|
||||||
|
utils::on_import_clicked(&window, &sender);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create the action that shows a `gtk::AboutDialog`
|
||||||
|
action!(
|
||||||
|
app,
|
||||||
|
"about",
|
||||||
|
clone!(app => move |_, _| {
|
||||||
|
let window = app.get_active_window().expect("Failed to get active window");
|
||||||
|
about_dialog(&window);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create the quit action
|
||||||
|
action!(app, "quit", clone!(app => move |_, _| app.quit()));
|
||||||
|
app.set_accels_for_action("app.quit", &["<primary>q"]);
|
||||||
|
|
||||||
|
// Bind the hamburger menu button to `F10`
|
||||||
|
app.set_accels_for_action("win.menu", &["F10"]);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run(self) {
|
pub fn run(self) {
|
||||||
WindowGeometry::from_settings(&self.settings).apply(&self.window);
|
|
||||||
|
|
||||||
let window = self.window.clone();
|
|
||||||
self.app_instance.connect_startup(move |app| {
|
|
||||||
build_ui(&window, app);
|
|
||||||
});
|
|
||||||
|
|
||||||
self.setup_timed_callbacks();
|
|
||||||
|
|
||||||
let content = self.content;
|
|
||||||
let headerbar = self.header;
|
|
||||||
let sender = self.sender;
|
|
||||||
let overlay = self.overlay;
|
|
||||||
let receiver = self.receiver;
|
|
||||||
gtk::timeout_add(50, move || {
|
|
||||||
match receiver.try_recv() {
|
|
||||||
Ok(Action::RefreshAllViews) => content.update(),
|
|
||||||
Ok(Action::RefreshShowsView) => content.update_shows_view(),
|
|
||||||
Ok(Action::RefreshWidgetIfSame(id)) => content.update_widget_if_same(id),
|
|
||||||
Ok(Action::RefreshEpisodesView) => content.update_home(),
|
|
||||||
Ok(Action::RefreshEpisodesViewBGR) => content.update_home_if_background(),
|
|
||||||
Ok(Action::ReplaceWidget(pd)) => {
|
|
||||||
let shows = content.get_shows();
|
|
||||||
let mut pop = shows.borrow().populated();
|
|
||||||
pop.borrow_mut()
|
|
||||||
.replace_widget(pd.clone())
|
|
||||||
.map_err(|err| error!("Failed to update ShowWidget: {}", err))
|
|
||||||
.map_err(|_| error!("Failed ot update ShowWidget {}", pd.title()))
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
Ok(Action::ShowWidgetAnimated) => {
|
|
||||||
let shows = content.get_shows();
|
|
||||||
let mut pop = shows.borrow().populated();
|
|
||||||
pop.borrow_mut().switch_visible(
|
|
||||||
PopulatedState::Widget,
|
|
||||||
gtk::StackTransitionType::SlideLeft,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok(Action::ShowShowsAnimated) => {
|
|
||||||
let shows = content.get_shows();
|
|
||||||
let mut pop = shows.borrow().populated();
|
|
||||||
pop.borrow_mut()
|
|
||||||
.switch_visible(PopulatedState::View, gtk::StackTransitionType::SlideRight);
|
|
||||||
}
|
|
||||||
Ok(Action::HeaderBarShowTile(title)) => headerbar.switch_to_back(&title),
|
|
||||||
Ok(Action::HeaderBarNormal) => headerbar.switch_to_normal(),
|
|
||||||
Ok(Action::HeaderBarShowUpdateIndicator) => headerbar.show_update_notification(),
|
|
||||||
Ok(Action::HeaderBarHideUpdateIndicator) => headerbar.hide_update_notification(),
|
|
||||||
Ok(Action::MarkAllPlayerNotification(pd)) => {
|
|
||||||
let notif = mark_all_notif(pd, &sender);
|
|
||||||
notif.show(&overlay);
|
|
||||||
}
|
|
||||||
Ok(Action::RemoveShow(pd)) => {
|
|
||||||
let notif = remove_show_notif(pd, sender.clone());
|
|
||||||
notif.show(&overlay);
|
|
||||||
}
|
|
||||||
Ok(Action::ErrorNotification(err)) => {
|
|
||||||
error!("An error notification was triggered: {}", err);
|
|
||||||
let callback = || glib::Continue(false);
|
|
||||||
let notif = InAppNotification::new(&err, callback, || {}, UndoState::Hidden);
|
|
||||||
notif.show(&overlay);
|
|
||||||
}
|
|
||||||
Err(_) => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
Continue(true)
|
|
||||||
});
|
|
||||||
|
|
||||||
ApplicationExtManual::run(&self.app_instance, &[]);
|
ApplicationExtManual::run(&self.app_instance, &[]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_ui(window: >k::Window, app: >k::Application) {
|
|
||||||
window.set_application(app);
|
|
||||||
window.show_all();
|
|
||||||
window.activate();
|
|
||||||
app.connect_activate(move |_| ());
|
|
||||||
}
|
|
||||||
|
|||||||
+30
-133
@@ -1,19 +1,18 @@
|
|||||||
|
use gio::MenuModel;
|
||||||
use glib;
|
use glib;
|
||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use failure::ResultExt;
|
use failure::ResultExt;
|
||||||
use rayon;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use hammond_data::{dbqueries, opml, Source};
|
use crossbeam_channel::Sender;
|
||||||
|
use hammond_data::{dbqueries, Source};
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
use stacks::Content;
|
use stacks::Content;
|
||||||
use utils::{self, itunes_to_rss, refresh};
|
use utils::{itunes_to_rss, refresh};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
// TODO: split this into smaller
|
// TODO: split this into smaller
|
||||||
@@ -23,31 +22,28 @@ pub struct Header {
|
|||||||
switch: gtk::StackSwitcher,
|
switch: gtk::StackSwitcher,
|
||||||
back: gtk::Button,
|
back: gtk::Button,
|
||||||
show_title: gtk::Label,
|
show_title: gtk::Label,
|
||||||
about: gtk::ModelButton,
|
|
||||||
import: gtk::ModelButton,
|
|
||||||
export: gtk::ModelButton,
|
|
||||||
update_button: gtk::ModelButton,
|
|
||||||
update_box: gtk::Box,
|
update_box: gtk::Box,
|
||||||
update_label: gtk::Label,
|
update_label: gtk::Label,
|
||||||
update_spinner: gtk::Spinner,
|
update_spinner: gtk::Spinner,
|
||||||
|
menu_button: gtk::MenuButton,
|
||||||
|
app_menu: MenuModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Header {
|
impl Default for Header {
|
||||||
fn default() -> Header {
|
fn default() -> Header {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/headerbar.ui");
|
||||||
|
let menus = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/menus.ui");
|
||||||
|
|
||||||
let header = builder.get_object("headerbar").unwrap();
|
let header = builder.get_object("headerbar").unwrap();
|
||||||
let add_toggle = builder.get_object("add_toggle").unwrap();
|
let add_toggle = builder.get_object("add_toggle").unwrap();
|
||||||
let switch = builder.get_object("switch").unwrap();
|
let switch = builder.get_object("switch").unwrap();
|
||||||
let back = builder.get_object("back").unwrap();
|
let back = builder.get_object("back").unwrap();
|
||||||
let show_title = builder.get_object("show_title").unwrap();
|
let show_title = builder.get_object("show_title").unwrap();
|
||||||
let import = builder.get_object("import").unwrap();
|
|
||||||
let export = builder.get_object("export").unwrap();
|
|
||||||
let update_button = builder.get_object("update_button").unwrap();
|
|
||||||
let update_box = builder.get_object("update_notification").unwrap();
|
let update_box = builder.get_object("update_notification").unwrap();
|
||||||
let update_label = builder.get_object("update_label").unwrap();
|
let update_label = builder.get_object("update_label").unwrap();
|
||||||
let update_spinner = builder.get_object("update_spinner").unwrap();
|
let update_spinner = builder.get_object("update_spinner").unwrap();
|
||||||
let about = builder.get_object("about").unwrap();
|
let menu_button = builder.get_object("menu_button").unwrap();
|
||||||
|
let app_menu = menus.get_object("menu").unwrap();
|
||||||
|
|
||||||
Header {
|
Header {
|
||||||
container: header,
|
container: header,
|
||||||
@@ -55,27 +51,34 @@ impl Default for Header {
|
|||||||
switch,
|
switch,
|
||||||
back,
|
back,
|
||||||
show_title,
|
show_title,
|
||||||
about,
|
|
||||||
import,
|
|
||||||
export,
|
|
||||||
update_button,
|
|
||||||
update_box,
|
update_box,
|
||||||
update_label,
|
update_label,
|
||||||
update_spinner,
|
update_spinner,
|
||||||
|
menu_button,
|
||||||
|
app_menu,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor components into smaller state machines
|
// TODO: Refactor components into smaller state machines
|
||||||
impl Header {
|
impl Header {
|
||||||
pub fn new(content: &Content, window: >k::Window, sender: &Sender<Action>) -> Header {
|
pub fn new(
|
||||||
|
content: &Content,
|
||||||
|
window: >k::ApplicationWindow,
|
||||||
|
sender: &Sender<Action>,
|
||||||
|
) -> Header {
|
||||||
let h = Header::default();
|
let h = Header::default();
|
||||||
h.init(content, window, &sender);
|
h.init(content, window, &sender);
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&self, content: &Content, window: >k::Window, sender: &Sender<Action>) {
|
pub fn init(
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui");
|
&self,
|
||||||
|
content: &Content,
|
||||||
|
window: >k::ApplicationWindow,
|
||||||
|
sender: &Sender<Action>,
|
||||||
|
) {
|
||||||
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/headerbar.ui");
|
||||||
|
|
||||||
let add_popover: gtk::Popover = builder.get_object("add_popover").unwrap();
|
let add_popover: gtk::Popover = builder.get_object("add_popover").unwrap();
|
||||||
let new_url: gtk::Entry = builder.get_object("new_url").unwrap();
|
let new_url: gtk::Entry = builder.get_object("new_url").unwrap();
|
||||||
@@ -98,22 +101,6 @@ impl Header {
|
|||||||
|
|
||||||
self.add_toggle.set_popover(&add_popover);
|
self.add_toggle.set_popover(&add_popover);
|
||||||
|
|
||||||
self.update_button
|
|
||||||
.connect_clicked(clone!(sender => move |_| {
|
|
||||||
gtk::idle_add(clone!(sender => move || {
|
|
||||||
let s: Option<Vec<_>> = None;
|
|
||||||
refresh(s, sender.clone());
|
|
||||||
glib::Continue(false)
|
|
||||||
}));
|
|
||||||
}));
|
|
||||||
|
|
||||||
self.about
|
|
||||||
.connect_clicked(clone!(window => move |_| about_dialog(&window)));
|
|
||||||
|
|
||||||
self.import.connect_clicked(
|
|
||||||
clone!(window, sender => move |_| on_import_clicked(&window, &sender)),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add the Headerbar to the window.
|
// Add the Headerbar to the window.
|
||||||
window.set_titlebar(&self.container);
|
window.set_titlebar(&self.container);
|
||||||
|
|
||||||
@@ -131,6 +118,8 @@ impl Header {
|
|||||||
.ok();
|
.ok();
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self.menu_button.set_menu_model(Some(&self.app_menu));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn switch_to_back(&self, title: &str) {
|
pub fn switch_to_back(&self, title: &str) {
|
||||||
@@ -165,6 +154,10 @@ impl Header {
|
|||||||
self.update_spinner.hide();
|
self.update_spinner.hide();
|
||||||
self.update_label.hide();
|
self.update_label.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn open_menu(&self) {
|
||||||
|
self.menu_button.clicked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: THIS ALSO SUCKS!
|
// FIXME: THIS ALSO SUCKS!
|
||||||
@@ -228,99 +221,3 @@ fn on_url_change(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_import_clicked(window: >k::Window, sender: &Sender<Action>) {
|
|
||||||
use glib::translate::ToGlib;
|
|
||||||
use gtk::{FileChooserAction, FileChooserDialog, FileFilter, ResponseType};
|
|
||||||
|
|
||||||
// let dialog = FileChooserDialog::new(title, Some(&window), FileChooserAction::Open);
|
|
||||||
// TODO: It might be better to use a FileChooserNative widget.
|
|
||||||
// Create the FileChooser Dialog
|
|
||||||
let dialog = FileChooserDialog::with_buttons(
|
|
||||||
Some("Select the file from which to you want to Import Shows."),
|
|
||||||
Some(window),
|
|
||||||
FileChooserAction::Open,
|
|
||||||
&[
|
|
||||||
("_Cancel", ResponseType::Cancel),
|
|
||||||
("_Open", ResponseType::Accept),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Do not show hidden(.thing) files
|
|
||||||
dialog.set_show_hidden(false);
|
|
||||||
|
|
||||||
// Set a filter to show only xml files
|
|
||||||
let filter = FileFilter::new();
|
|
||||||
FileFilterExt::set_name(&filter, Some("OPML file"));
|
|
||||||
filter.add_mime_type("application/xml");
|
|
||||||
filter.add_mime_type("text/xml");
|
|
||||||
dialog.add_filter(&filter);
|
|
||||||
|
|
||||||
dialog.connect_response(clone!(sender => move |dialog, resp| {
|
|
||||||
debug!("Dialong Response {}", resp);
|
|
||||||
if resp == ResponseType::Accept.to_glib() {
|
|
||||||
// TODO: Show an in-app notifictaion if the file can not be accessed
|
|
||||||
if let Some(filename) = dialog.get_filename() {
|
|
||||||
debug!("File selected: {:?}", filename);
|
|
||||||
|
|
||||||
rayon::spawn(clone!(sender => move || {
|
|
||||||
// Parse the file and import the feeds
|
|
||||||
if let Ok(sources) = opml::import_from_file(filename) {
|
|
||||||
// Refresh the succesfully parsed feeds to index them
|
|
||||||
utils::refresh(Some(sources), sender)
|
|
||||||
} else {
|
|
||||||
let text = String::from("Failed to parse the Imported file");
|
|
||||||
sender.send(Action::ErrorNotification(text))
|
|
||||||
.map_err(|err| error!("Action Sender: {}", err))
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
let text = String::from("Selected File could not be accessed.");
|
|
||||||
sender.send(Action::ErrorNotification(text))
|
|
||||||
.map_err(|err| error!("Action Sender: {}", err))
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog.destroy();
|
|
||||||
}));
|
|
||||||
|
|
||||||
dialog.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Totally copied it from fractal.
|
|
||||||
// https://gitlab.gnome.org/danigm/fractal/blob/503e311e22b9d7540089d735b92af8e8f93560c5/fractal-gtk/src/app.rs#L1883-1912
|
|
||||||
fn about_dialog(window: >k::Window) {
|
|
||||||
// Feel free to add yourself if you contribured.
|
|
||||||
let authors = &[
|
|
||||||
"Constantin Nickel",
|
|
||||||
"Gabriele Musco",
|
|
||||||
"James Wykeham-Martin",
|
|
||||||
"Jordan Petridis",
|
|
||||||
"Julian Sparber",
|
|
||||||
"Rowan Lewis",
|
|
||||||
];
|
|
||||||
|
|
||||||
let dialog = gtk::AboutDialog::new();
|
|
||||||
// Waiting for a logo.
|
|
||||||
// dialog.set_logo_icon_name("org.gnome.Hammond");
|
|
||||||
dialog.set_logo_icon_name("multimedia-player");
|
|
||||||
dialog.set_comments("Podcast Client for the GNOME Desktop.");
|
|
||||||
dialog.set_copyright("© 2017, 2018 Jordan Petridis");
|
|
||||||
dialog.set_license_type(gtk::License::Gpl30);
|
|
||||||
dialog.set_modal(true);
|
|
||||||
// TODO: make it show it fetches the commit hash from which it was built
|
|
||||||
// and the version number is kept in sync automaticly
|
|
||||||
dialog.set_version("0.3.3");
|
|
||||||
dialog.set_program_name("Hammond");
|
|
||||||
// TODO: Need a wiki page first.
|
|
||||||
// dialog.set_website("https://wiki.gnome.org/Design/Apps/Potential/Podcasts");
|
|
||||||
// dialog.set_website_label("Learn more about Hammond");
|
|
||||||
dialog.set_transient_for(window);
|
|
||||||
|
|
||||||
dialog.set_artists(&["Tobias Bernard"]);
|
|
||||||
dialog.set_authors(authors);
|
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ extern crate regex;
|
|||||||
extern crate reqwest;
|
extern crate reqwest;
|
||||||
extern crate send_cell;
|
extern crate send_cell;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate take_mut;
|
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
use log::Level;
|
use log::Level;
|
||||||
@@ -70,7 +69,6 @@ mod widgets;
|
|||||||
mod app;
|
mod app;
|
||||||
mod headerbar;
|
mod headerbar;
|
||||||
|
|
||||||
mod appnotif;
|
|
||||||
mod manager;
|
mod manager;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod static_resource;
|
mod static_resource;
|
||||||
@@ -86,7 +84,7 @@ fn main() {
|
|||||||
|
|
||||||
// Add custom style
|
// Add custom style
|
||||||
let provider = gtk::CssProvider::new();
|
let provider = gtk::CssProvider::new();
|
||||||
gtk::CssProvider::load_from_resource(&provider, "/org/gnome/hammond/gtk/style.css");
|
gtk::CssProvider::load_from_resource(&provider, "/org/gnome/Hammond/gtk/style.css");
|
||||||
gtk::StyleContext::add_provider_for_screen(
|
gtk::StyleContext::add_provider_for_screen(
|
||||||
&gdk::Screen::get_default().expect("Error initializing gtk css provider."),
|
&gdk::Screen::get_default().expect("Error initializing gtk css provider."),
|
||||||
&provider,
|
&provider,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub struct WindowGeometry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WindowGeometry {
|
impl WindowGeometry {
|
||||||
pub fn from_window(window: >k::Window) -> WindowGeometry {
|
pub fn from_window(window: >k::ApplicationWindow) -> WindowGeometry {
|
||||||
let position = window.get_position();
|
let position = window.get_position();
|
||||||
let size = window.get_size();
|
let size = window.get_size();
|
||||||
let left = position.0;
|
let left = position.0;
|
||||||
@@ -49,7 +49,7 @@ impl WindowGeometry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply(&self, window: >k::Window) {
|
pub fn apply(&self, window: >k::ApplicationWindow) {
|
||||||
if self.width > 0 && self.height > 0 {
|
if self.width > 0 && self.height > 0 {
|
||||||
window.resize(self.width, self.height);
|
window.resize(self.width, self.height);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
@@ -8,7 +9,6 @@ use stacks::{HomeStack, ShowStack};
|
|||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Content {
|
pub struct Content {
|
||||||
@@ -85,4 +85,8 @@ impl Content {
|
|||||||
pub fn get_shows(&self) -> Rc<RefCell<ShowStack>> {
|
pub fn get_shows(&self) -> Rc<RefCell<ShowStack>> {
|
||||||
self.shows.clone()
|
self.shows.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_visible_stack(&self) -> Option<gtk::Stack> {
|
||||||
|
self.stack.get_visible_child().and_then(|w| w.downcast::<gtk::Stack>().ok())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use gtk;
|
|||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::StackTransitionType;
|
use gtk::StackTransitionType;
|
||||||
|
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use hammond_data::dbqueries::is_episodes_populated;
|
use hammond_data::dbqueries::is_episodes_populated;
|
||||||
use hammond_data::errors::DataError;
|
use hammond_data::errors::DataError;
|
||||||
@@ -10,7 +11,6 @@ use app::Action;
|
|||||||
use widgets::{EmptyView, HomeView};
|
use widgets::{EmptyView, HomeView};
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum State {
|
enum State {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use gtk;
|
|||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::StackTransitionType;
|
use gtk::StackTransitionType;
|
||||||
|
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
|
||||||
use hammond_data::dbqueries;
|
use hammond_data::dbqueries;
|
||||||
@@ -11,7 +12,6 @@ use app::Action;
|
|||||||
use widgets::{ShowWidget, ShowsView};
|
use widgets::{ShowWidget, ShowsView};
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use hammond_data::dbqueries::is_podcasts_populated;
|
use hammond_data::dbqueries::is_podcasts_populated;
|
||||||
|
|
||||||
@@ -11,7 +12,6 @@ use widgets::EmptyView;
|
|||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum ShowState {
|
pub enum ShowState {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use gtk::prelude::*;
|
|||||||
use gtk::{IsA, Widget};
|
use gtk::{IsA, Widget};
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use rayon;
|
use rayon;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
@@ -17,15 +18,15 @@ use serde_json::Value;
|
|||||||
|
|
||||||
// use hammond_data::feed;
|
// use hammond_data::feed;
|
||||||
use hammond_data::dbqueries;
|
use hammond_data::dbqueries;
|
||||||
|
use hammond_data::opml;
|
||||||
use hammond_data::pipeline;
|
use hammond_data::pipeline;
|
||||||
use hammond_data::utils::checkup;
|
use hammond_data::utils::checkup;
|
||||||
use hammond_data::Source;
|
use hammond_data::Source;
|
||||||
use hammond_downloader::downloader;
|
use hammond_downloader::downloader;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::sync::mpsc::*;
|
use std::sync::mpsc::channel;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::sync::{Mutex, RwLock};
|
|
||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ use app::Action;
|
|||||||
///
|
///
|
||||||
/// let messages: Vec<Message> = Vec::new();
|
/// let messages: Vec<Message> = Vec::new();
|
||||||
/// let list = gtk::ListBox::new();
|
/// let list = gtk::ListBox::new();
|
||||||
/// let constructor = |m| { MessageWidget::new(m).0};
|
/// let constructor = |m| MessageWidget::new(m).0;
|
||||||
/// lazy_load(messages, list, constructor, || {});
|
/// lazy_load(messages, list, constructor, || {});
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
@@ -333,6 +334,64 @@ fn lookup_id(id: u32) -> Result<String, Error> {
|
|||||||
.ok_or_else(|| format_err!("Failed to get url from itunes response"))
|
.ok_or_else(|| format_err!("Failed to get url from itunes response"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_import_clicked(window: >k::Window, sender: &Sender<Action>) {
|
||||||
|
use glib::translate::ToGlib;
|
||||||
|
use gtk::{FileChooserAction, FileChooserNative, FileFilter, ResponseType};
|
||||||
|
|
||||||
|
// let dialog = FileChooserDialog::new(title, Some(&window), FileChooserAction::Open);
|
||||||
|
// TODO: It might be better to use a FileChooserNative widget.
|
||||||
|
// Create the FileChooser Dialog
|
||||||
|
let dialog = FileChooserNative::new(
|
||||||
|
Some("Select the file from which to you want to Import Shows."),
|
||||||
|
Some(window),
|
||||||
|
FileChooserAction::Open,
|
||||||
|
Some("_Import"),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Do not show hidden(.thing) files
|
||||||
|
dialog.set_show_hidden(false);
|
||||||
|
|
||||||
|
// Set a filter to show only xml files
|
||||||
|
let filter = FileFilter::new();
|
||||||
|
FileFilterExt::set_name(&filter, Some("OPML file"));
|
||||||
|
filter.add_mime_type("application/xml");
|
||||||
|
filter.add_mime_type("text/xml");
|
||||||
|
dialog.add_filter(&filter);
|
||||||
|
|
||||||
|
dialog.connect_response(clone!(sender => move |dialog, resp| {
|
||||||
|
debug!("Dialong Response {}", resp);
|
||||||
|
if resp == ResponseType::Accept.to_glib() {
|
||||||
|
// TODO: Show an in-app notifictaion if the file can not be accessed
|
||||||
|
if let Some(filename) = dialog.get_filename() {
|
||||||
|
debug!("File selected: {:?}", filename);
|
||||||
|
|
||||||
|
rayon::spawn(clone!(sender => move || {
|
||||||
|
// Parse the file and import the feeds
|
||||||
|
if let Ok(sources) = opml::import_from_file(filename) {
|
||||||
|
// Refresh the succesfully parsed feeds to index them
|
||||||
|
refresh(Some(sources), sender)
|
||||||
|
} else {
|
||||||
|
let text = String::from("Failed to parse the Imported file");
|
||||||
|
sender.send(Action::ErrorNotification(text))
|
||||||
|
.map_err(|err| error!("Action Sender: {}", err))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
let text = String::from("Selected File could not be accessed.");
|
||||||
|
sender.send(Action::ErrorNotification(text))
|
||||||
|
.map_err(|err| error!("Action Sender: {}", err))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.destroy();
|
||||||
|
}));
|
||||||
|
|
||||||
|
dialog.run();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
use gtk;
|
||||||
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
// Totally copied it from fractal.
|
||||||
|
// https://gitlab.gnome.org/danigm/fractal/blob/503e311e22b9d7540089d735b92af8e8f93560c5/fractal-gtk/src/app.rs#L1883-1912
|
||||||
|
/// Given a `window` create and attach an `gtk::AboutDialog` to it.
|
||||||
|
pub fn about_dialog(window: >k::Window) {
|
||||||
|
// Feel free to add yourself if you contribured.
|
||||||
|
let authors = &[
|
||||||
|
"Constantin Nickel",
|
||||||
|
"Gabriele Musco",
|
||||||
|
"James Wykeham-Martin",
|
||||||
|
"Jordan Petridis",
|
||||||
|
"Julian Sparber",
|
||||||
|
"Rowan Lewis",
|
||||||
|
"Zander Brown",
|
||||||
|
];
|
||||||
|
|
||||||
|
let dialog = gtk::AboutDialog::new();
|
||||||
|
// Waiting for a logo.
|
||||||
|
// dialog.set_logo_icon_name("org.gnome.Hammond");
|
||||||
|
dialog.set_logo_icon_name("multimedia-player");
|
||||||
|
dialog.set_comments("Podcast Client for the GNOME Desktop.");
|
||||||
|
dialog.set_copyright("© 2017, 2018 Jordan Petridis");
|
||||||
|
dialog.set_license_type(gtk::License::Gpl30);
|
||||||
|
dialog.set_modal(true);
|
||||||
|
// TODO: make it show it fetches the commit hash from which it was built
|
||||||
|
// and the version number is kept in sync automaticly
|
||||||
|
dialog.set_version("0.3.4");
|
||||||
|
dialog.set_program_name("Hammond");
|
||||||
|
// TODO: Need a wiki page first.
|
||||||
|
// dialog.set_website("https://wiki.gnome.org/Design/Apps/Potential/Podcasts");
|
||||||
|
// dialog.set_website_label("Learn more about Hammond");
|
||||||
|
dialog.set_transient_for(window);
|
||||||
|
|
||||||
|
dialog.set_artists(&["Tobias Bernard"]);
|
||||||
|
dialog.set_authors(authors);
|
||||||
|
|
||||||
|
dialog.connect_response(|dlg, _| dlg.destroy());
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ pub struct InAppNotification {
|
|||||||
|
|
||||||
impl Default for InAppNotification {
|
impl Default for InAppNotification {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/inapp_notif.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/inapp_notif.ui");
|
||||||
|
|
||||||
let revealer: gtk::Revealer = builder.get_object("revealer").unwrap();
|
let revealer: gtk::Revealer = builder.get_object("revealer").unwrap();
|
||||||
let text: gtk::Label = builder.get_object("text").unwrap();
|
let text: gtk::Label = builder.get_object("text").unwrap();
|
||||||
@@ -7,7 +7,7 @@ pub struct EmptyView {
|
|||||||
|
|
||||||
impl Default for EmptyView {
|
impl Default for EmptyView {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_view.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/empty_view.ui");
|
||||||
let view: gtk::Box = builder.get_object("empty_view").unwrap();
|
let view: gtk::Box = builder.get_object("empty_view").unwrap();
|
||||||
|
|
||||||
EmptyView { container: view }
|
EmptyView { container: view }
|
||||||
|
|||||||
+433
-223
@@ -2,10 +2,12 @@ use glib;
|
|||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
use chrono;
|
||||||
|
use chrono::prelude::*;
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use humansize::FileSize;
|
use humansize::{file_size_opts as size_opts, FileSize};
|
||||||
use open;
|
use open;
|
||||||
use take_mut;
|
|
||||||
|
|
||||||
use hammond_data::dbqueries;
|
use hammond_data::dbqueries;
|
||||||
use hammond_data::utils::get_download_folder;
|
use hammond_data::utils::get_download_folder;
|
||||||
@@ -13,224 +15,446 @@ use hammond_data::EpisodeWidgetQuery;
|
|||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
use manager;
|
use manager;
|
||||||
use widgets::episode_states::*;
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::ops::DerefMut;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::{Arc, Mutex, TryLockError};
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
lazy_static! {
|
||||||
|
static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = {
|
||||||
|
// Declare a custom humansize option struct
|
||||||
|
// See: https://docs.rs/humansize/1.0.2/humansize/file_size_opts/struct.FileSizeOpts.html
|
||||||
|
Arc::new(size_opts::FileSizeOpts {
|
||||||
|
divider: size_opts::Kilo::Binary,
|
||||||
|
units: size_opts::Kilo::Decimal,
|
||||||
|
decimal_places: 0,
|
||||||
|
decimal_zeroes: 0,
|
||||||
|
fixed_at: size_opts::FixedAt::No,
|
||||||
|
long_units: false,
|
||||||
|
space: true,
|
||||||
|
suffix: "",
|
||||||
|
allow_negative: false,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct EpisodeWidget {
|
pub struct EpisodeWidget {
|
||||||
pub container: gtk::Box,
|
pub container: gtk::Box,
|
||||||
date: DateMachine,
|
info: InfoLabels,
|
||||||
duration: DurationMachine,
|
buttons: Buttons,
|
||||||
title: Rc<RefCell<TitleMachine>>,
|
progressbar: gtk::ProgressBar,
|
||||||
media: Rc<RefCell<MediaMachine>>,
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct InfoLabels {
|
||||||
|
container: gtk::Box,
|
||||||
|
title: gtk::Label,
|
||||||
|
date: gtk::Label,
|
||||||
|
separator1: gtk::Label,
|
||||||
|
duration: gtk::Label,
|
||||||
|
separator2: gtk::Label,
|
||||||
|
local_size: gtk::Label,
|
||||||
|
size_separator: gtk::Label,
|
||||||
|
total_size: gtk::Label,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct Buttons {
|
||||||
|
container: gtk::ButtonBox,
|
||||||
|
play: gtk::Button,
|
||||||
|
download: gtk::Button,
|
||||||
|
cancel: gtk::Button,
|
||||||
|
desc: gtk::Button,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InfoLabels {
|
||||||
|
fn init(&self, episode: &EpisodeWidgetQuery) {
|
||||||
|
// Set the title label state.
|
||||||
|
self.set_title(episode);
|
||||||
|
|
||||||
|
// Set the date label.
|
||||||
|
self.set_date(episode.epoch());
|
||||||
|
|
||||||
|
// Set the duaration label.
|
||||||
|
self.set_duration(episode.duration());
|
||||||
|
|
||||||
|
// Set the total_size label.
|
||||||
|
self.set_size(episode.length())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_title(&self, episode: &EpisodeWidgetQuery) {
|
||||||
|
self.title.set_text(episode.title());
|
||||||
|
|
||||||
|
if episode.played().is_some() {
|
||||||
|
self.title
|
||||||
|
.get_style_context()
|
||||||
|
.map(|c| c.add_class("dim-label"));
|
||||||
|
} else {
|
||||||
|
self.title
|
||||||
|
.get_style_context()
|
||||||
|
.map(|c| c.remove_class("dim-label"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the date label of the episode widget.
|
||||||
|
fn set_date(&self, epoch: i32) {
|
||||||
|
lazy_static! {
|
||||||
|
static ref NOW: DateTime<Utc> = Utc::now();
|
||||||
|
};
|
||||||
|
|
||||||
|
let ts = Utc.timestamp(i64::from(epoch), 0);
|
||||||
|
|
||||||
|
// If the episode is from a different year, print year as well
|
||||||
|
if NOW.year() != ts.year() {
|
||||||
|
self.date.set_text(ts.format("%e %b %Y").to_string().trim());
|
||||||
|
// Else omit the year from the label
|
||||||
|
} else {
|
||||||
|
self.date.set_text(ts.format("%e %b").to_string().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the duration label of the episode widget.
|
||||||
|
fn set_duration(&self, seconds: Option<i32>) {
|
||||||
|
// If lenght is provided
|
||||||
|
if let Some(s) = seconds {
|
||||||
|
// Convert seconds to minutes
|
||||||
|
let minutes = chrono::Duration::seconds(s.into()).num_minutes();
|
||||||
|
// If the lenght is 1 or more minutes
|
||||||
|
if minutes != 0 {
|
||||||
|
// Set the label and show them.
|
||||||
|
self.duration.set_text(&format!("{} min", minutes));
|
||||||
|
self.duration.show();
|
||||||
|
self.separator1.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else hide the labels
|
||||||
|
self.separator1.hide();
|
||||||
|
self.duration.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the size label of the episode widget.
|
||||||
|
fn set_size(&self, bytes: Option<i32>) {
|
||||||
|
// Convert the bytes to a String label
|
||||||
|
let size = || -> Option<String> {
|
||||||
|
let s = bytes?;
|
||||||
|
if s == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
s.file_size(SIZE_OPTS.clone()).ok()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(s) = size() {
|
||||||
|
self.total_size.set_text(&s);
|
||||||
|
self.total_size.show();
|
||||||
|
self.separator2.show();
|
||||||
|
} else {
|
||||||
|
self.total_size.hide();
|
||||||
|
self.separator2.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EpisodeWidget {
|
impl Default for EpisodeWidget {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episode_widget.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/episode_widget.ui");
|
||||||
|
|
||||||
let container: gtk::Box = builder.get_object("episode_container").unwrap();
|
let container = builder.get_object("episode_container").unwrap();
|
||||||
let progress: gtk::ProgressBar = builder.get_object("progress_bar").unwrap();
|
let progressbar = builder.get_object("progress_bar").unwrap();
|
||||||
|
|
||||||
let download: gtk::Button = builder.get_object("download_button").unwrap();
|
let buttons_container = builder.get_object("button_box").unwrap();
|
||||||
let play: gtk::Button = builder.get_object("play_button").unwrap();
|
let download = builder.get_object("download_button").unwrap();
|
||||||
let cancel: gtk::Button = builder.get_object("cancel_button").unwrap();
|
let play = builder.get_object("play_button").unwrap();
|
||||||
|
let cancel = builder.get_object("cancel_button").unwrap();
|
||||||
|
let desc_button = builder.get_object("desc_button").unwrap();
|
||||||
|
|
||||||
let title: gtk::Label = builder.get_object("title_label").unwrap();
|
let info_container = builder.get_object("info_container").unwrap();
|
||||||
let date: gtk::Label = builder.get_object("date_label").unwrap();
|
let title = builder.get_object("title_label").unwrap();
|
||||||
let duration: gtk::Label = builder.get_object("duration_label").unwrap();
|
let date = builder.get_object("date_label").unwrap();
|
||||||
let local_size: gtk::Label = builder.get_object("local_size").unwrap();
|
let duration = builder.get_object("duration_label").unwrap();
|
||||||
let total_size: gtk::Label = builder.get_object("total_size").unwrap();
|
let local_size = builder.get_object("local_size").unwrap();
|
||||||
|
let total_size = builder.get_object("total_size").unwrap();
|
||||||
|
|
||||||
let separator1: gtk::Label = builder.get_object("separator1").unwrap();
|
let separator1 = builder.get_object("separator1").unwrap();
|
||||||
let separator2: gtk::Label = builder.get_object("separator2").unwrap();
|
let separator2 = builder.get_object("separator2").unwrap();
|
||||||
let prog_separator: gtk::Label = builder.get_object("prog_separator").unwrap();
|
|
||||||
|
|
||||||
let date_machine = DateMachine::new(date, 0);
|
let size_separator = builder.get_object("prog_separator").unwrap();
|
||||||
let dur_machine = DurationMachine::new(duration, separator1, None);
|
|
||||||
let title_machine = Rc::new(RefCell::new(TitleMachine::new(title, false)));
|
|
||||||
let media = MediaMachine::new(
|
|
||||||
play,
|
|
||||||
download,
|
|
||||||
progress,
|
|
||||||
cancel,
|
|
||||||
total_size,
|
|
||||||
local_size,
|
|
||||||
separator2,
|
|
||||||
prog_separator,
|
|
||||||
);
|
|
||||||
let media_machine = Rc::new(RefCell::new(media));
|
|
||||||
|
|
||||||
EpisodeWidget {
|
EpisodeWidget {
|
||||||
|
info: InfoLabels {
|
||||||
|
container: info_container,
|
||||||
|
title,
|
||||||
|
date,
|
||||||
|
separator1,
|
||||||
|
duration,
|
||||||
|
separator2,
|
||||||
|
local_size,
|
||||||
|
total_size,
|
||||||
|
size_separator,
|
||||||
|
},
|
||||||
|
buttons: Buttons {
|
||||||
|
container: buttons_container,
|
||||||
|
play,
|
||||||
|
download,
|
||||||
|
cancel,
|
||||||
|
desc: desc_button,
|
||||||
|
},
|
||||||
|
progressbar,
|
||||||
container,
|
container,
|
||||||
title: title_machine,
|
|
||||||
duration: dur_machine,
|
|
||||||
date: date_machine,
|
|
||||||
media: media_machine,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EpisodeWidget {
|
impl EpisodeWidget {
|
||||||
pub fn new(episode: EpisodeWidgetQuery, sender: &Sender<Action>) -> EpisodeWidget {
|
pub fn new(episode: &EpisodeWidgetQuery, sender: &Sender<Action>) -> Rc<Self> {
|
||||||
let mut widget = EpisodeWidget::default();
|
let widget = Rc::new(Self::default());
|
||||||
widget.init(episode, sender);
|
widget.info.init(episode);
|
||||||
|
Self::determine_buttons_state(&widget, episode, sender)
|
||||||
|
.map_err(|err| error!("Error: {}", err))
|
||||||
|
.ok();
|
||||||
|
widget
|
||||||
|
.on_desc_clicked(episode, sender)
|
||||||
|
.map_err(|err| error!("Error: {}", err))
|
||||||
|
.ok();
|
||||||
widget
|
widget
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&mut self, episode: EpisodeWidgetQuery, sender: &Sender<Action>) {
|
fn on_desc_clicked(
|
||||||
// Set the date label.
|
&self,
|
||||||
self.set_date(episode.epoch());
|
episode: &EpisodeWidgetQuery,
|
||||||
|
sender: &Sender<Action>,
|
||||||
// Set the title label state.
|
) -> Result<(), Error> {
|
||||||
self.set_title(&episode);
|
let id = episode.rowid();
|
||||||
|
if dbqueries::episode_had_description(id)? {
|
||||||
// Set the duaration label.
|
self.buttons.desc.show();
|
||||||
self.set_duration(episode.duration());
|
self.buttons
|
||||||
|
.desc
|
||||||
// Determine what the state of the media widgets should be.
|
.connect_clicked(clone!(sender => move |_| {
|
||||||
determine_media_state(&self.media, &episode)
|
sender.send(Action::AboutWidget(id))
|
||||||
.map_err(|err| error!("Error: {}", err))
|
.map_err(|err| error!("Action Sender: {}", err))
|
||||||
.map_err(|_| error!("Could not determine Media State"))
|
.ok();
|
||||||
.ok();
|
}));
|
||||||
|
Ok(())
|
||||||
let episode = Arc::new(Mutex::new(episode));
|
} else {
|
||||||
self.connect_buttons(&episode, sender);
|
self.buttons.desc.hide();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connect_buttons(&self, episode: &Arc<Mutex<EpisodeWidgetQuery>>, sender: &Sender<Action>) {
|
// fn init(widget: Rc<Self>, sender: &Sender<Action>) {}
|
||||||
let title = self.title.clone();
|
|
||||||
if let Ok(media) = self.media.try_borrow_mut() {
|
// InProgress State:
|
||||||
media.play_connect_clicked(clone!(episode, sender => move |_| {
|
// * Show ProgressBar and Cancel Button.
|
||||||
if let Ok(mut ep) = episode.lock() {
|
// * Show `total_size`, `local_size` labels and `size_separator`.
|
||||||
on_play_bttn_clicked(&mut ep, &title, &sender)
|
// * Hide Download and Play Buttons
|
||||||
.map_err(|err| error!("Error: {}", err))
|
fn state_prog(&self) {
|
||||||
.ok();
|
self.progressbar.show();
|
||||||
|
self.buttons.cancel.show();
|
||||||
|
|
||||||
|
self.info.total_size.show();
|
||||||
|
self.info.local_size.show();
|
||||||
|
self.info.size_separator.show();
|
||||||
|
|
||||||
|
self.buttons.play.hide();
|
||||||
|
self.buttons.download.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Playable State:
|
||||||
|
// * Hide ProgressBar and Cancel, Download Buttons.
|
||||||
|
// * Hide `local_size` labels and `size_separator`.
|
||||||
|
// * Show Play Button and `total_size` label
|
||||||
|
fn state_playable(&self) {
|
||||||
|
self.progressbar.hide();
|
||||||
|
self.buttons.cancel.hide();
|
||||||
|
self.buttons.download.hide();
|
||||||
|
self.info.local_size.hide();
|
||||||
|
self.info.size_separator.hide();
|
||||||
|
|
||||||
|
self.info.total_size.show();
|
||||||
|
self.buttons.play.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDownload State:
|
||||||
|
// * Hide ProgressBar and Cancel, Play Buttons.
|
||||||
|
// * Hide `local_size` labels and `size_separator`.
|
||||||
|
// * Show Download Button
|
||||||
|
// * Determine `total_size` label state (Comes from `episode.lenght`).
|
||||||
|
fn state_download(&self) {
|
||||||
|
self.progressbar.hide();
|
||||||
|
self.buttons.cancel.hide();
|
||||||
|
self.buttons.play.hide();
|
||||||
|
|
||||||
|
self.info.local_size.hide();
|
||||||
|
self.info.size_separator.hide();
|
||||||
|
|
||||||
|
self.buttons.download.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_progress(&self, local_size: &str, fraction: f64) {
|
||||||
|
self.info.local_size.set_text(local_size);
|
||||||
|
self.progressbar.set_fraction(fraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change the state of the `EpisodeWidget`.
|
||||||
|
///
|
||||||
|
/// Function Flowchart:
|
||||||
|
///
|
||||||
|
/// ------------------- --------------
|
||||||
|
/// | Is the Episode | YES | State: |
|
||||||
|
/// | currently being | ----> | InProgress |
|
||||||
|
/// | downloaded? | | |
|
||||||
|
/// ------------------- --------------
|
||||||
|
/// |
|
||||||
|
/// | NO
|
||||||
|
/// |
|
||||||
|
/// \_/
|
||||||
|
/// ------------------- --------------
|
||||||
|
/// | is the episode | YES | State: |
|
||||||
|
/// | downloaded | ----> | Playable |
|
||||||
|
/// | already? | | |
|
||||||
|
/// ------------------- --------------
|
||||||
|
/// |
|
||||||
|
/// | NO
|
||||||
|
/// |
|
||||||
|
/// \_/
|
||||||
|
/// -------------------
|
||||||
|
/// | State: |
|
||||||
|
/// | ToDownload |
|
||||||
|
/// -------------------
|
||||||
|
fn determine_buttons_state(
|
||||||
|
widget: &Rc<Self>,
|
||||||
|
episode: &EpisodeWidgetQuery,
|
||||||
|
sender: &Sender<Action>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// Reset the buttons state no matter the glade file.
|
||||||
|
// This is just to make it easier to port to relm in the future.
|
||||||
|
widget.buttons.cancel.hide();
|
||||||
|
widget.buttons.play.hide();
|
||||||
|
widget.buttons.download.hide();
|
||||||
|
|
||||||
|
// Check if the episode is being downloaded
|
||||||
|
let id = episode.rowid();
|
||||||
|
let active_dl = move || -> Result<Option<_>, Error> {
|
||||||
|
let m = manager::ACTIVE_DOWNLOADS
|
||||||
|
.read()
|
||||||
|
.map_err(|_| format_err!("Failed to get a lock on the mutex."))?;
|
||||||
|
|
||||||
|
Ok(m.get(&id).cloned())
|
||||||
|
};
|
||||||
|
|
||||||
|
// State: InProggress
|
||||||
|
if let Some(prog) = active_dl()? {
|
||||||
|
// set a callback that will update the state when the download finishes
|
||||||
|
let callback = clone!(widget, sender => move || {
|
||||||
|
if let Ok(guard) = manager::ACTIVE_DOWNLOADS.read() {
|
||||||
|
if !guard.contains_key(&id) {
|
||||||
|
if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
|
Self::determine_buttons_state(&widget, &ep, &sender)
|
||||||
|
.map_err(|err| error!("Error: {}", err))
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
return glib::Continue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glib::Continue(true)
|
||||||
|
});
|
||||||
|
gtk::timeout_add(250, callback);
|
||||||
|
|
||||||
|
// Wire the cancel button
|
||||||
|
widget
|
||||||
|
.buttons
|
||||||
|
.cancel
|
||||||
|
.connect_clicked(clone!(prog, widget, sender => move |_| {
|
||||||
|
// Cancel the download
|
||||||
|
if let Ok(mut m) = prog.lock() {
|
||||||
|
m.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel is not instant so we have to wait a bit
|
||||||
|
timeout_add(50, clone!(widget, sender => move || {
|
||||||
|
if let Ok(thing) = active_dl() {
|
||||||
|
if thing.is_none() {
|
||||||
|
// Recalculate the widget state
|
||||||
|
dbqueries::get_episode_widget_from_rowid(id)
|
||||||
|
.map_err(From::from)
|
||||||
|
.and_then(|ep| Self::determine_buttons_state(&widget, &ep, &sender))
|
||||||
|
.map_err(|err| error!("Error: {}", err))
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
return glib::Continue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::Continue(true)
|
||||||
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let media_machine = self.media.clone();
|
// Setup a callback that will update the total_size label
|
||||||
media.download_connect_clicked(clone!(media_machine, episode, sender => move |dl| {
|
// with the http ContentLength header number rather than
|
||||||
|
// relying to the RSS feed.
|
||||||
|
update_total_size_callback(&widget, &prog);
|
||||||
|
|
||||||
|
// Setup a callback that will update the progress bar.
|
||||||
|
update_progressbar_callback(&widget, &prog, id);
|
||||||
|
|
||||||
|
// Change the widget layout/state
|
||||||
|
widget.state_prog();
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// State: Playable
|
||||||
|
if episode.local_uri().is_some() {
|
||||||
|
// Change the widget layout/state
|
||||||
|
widget.state_playable();
|
||||||
|
|
||||||
|
// Wire the play button
|
||||||
|
widget
|
||||||
|
.buttons
|
||||||
|
.play
|
||||||
|
.connect_clicked(clone!(widget, sender => move |_| {
|
||||||
|
if let Ok(mut ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
|
on_play_bttn_clicked(&widget, &mut ep, &sender)
|
||||||
|
.map_err(|err| error!("Error: {}", err))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// State: ToDownload
|
||||||
|
// Wire the download button
|
||||||
|
widget
|
||||||
|
.buttons
|
||||||
|
.download
|
||||||
|
.connect_clicked(clone!(widget, sender => move |dl| {
|
||||||
// Make the button insensitive so it won't be pressed twice
|
// Make the button insensitive so it won't be pressed twice
|
||||||
dl.set_sensitive(false);
|
dl.set_sensitive(false);
|
||||||
if let Ok(ep) = episode.lock() {
|
if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
on_download_clicked(&ep, &sender)
|
on_download_clicked(&ep, &sender)
|
||||||
.and_then(|_| {
|
.and_then(|_| {
|
||||||
info!("Donwload started succesfully.");
|
info!("Donwload started succesfully.");
|
||||||
determine_media_state(&media_machine, &ep)
|
Self::determine_buttons_state(&widget, &ep, &sender)
|
||||||
})
|
})
|
||||||
.map_err(|err| error!("Error: {}", err))
|
.map_err(|err| error!("Error: {}", err))
|
||||||
.map_err(|_| error!("Could not determine Media State"))
|
.ok();
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore sensitivity after operations above complete
|
// Restore sensitivity after operations above complete
|
||||||
dl.set_sensitive(true);
|
dl.set_sensitive(true);
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
|
// Change the widget state into `ToDownload`
|
||||||
|
widget.state_download();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine the title state.
|
|
||||||
fn set_title(&mut self, episode: &EpisodeWidgetQuery) {
|
|
||||||
let mut machine = self.title.borrow_mut();
|
|
||||||
machine.set_title(episode.title());
|
|
||||||
take_mut::take(machine.deref_mut(), |title| {
|
|
||||||
title.determine_state(episode.played().is_some())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the date label depending on the current time.
|
|
||||||
fn set_date(&mut self, epoch: i32) {
|
|
||||||
let machine = &mut self.date;
|
|
||||||
take_mut::take(machine, |date| date.determine_state(i64::from(epoch)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the duration label.
|
|
||||||
fn set_duration(&mut self, seconds: Option<i32>) {
|
|
||||||
let machine = &mut self.duration;
|
|
||||||
take_mut::take(machine, |duration| duration.determine_state(seconds));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn determine_media_state(
|
|
||||||
media_machine: &Rc<RefCell<MediaMachine>>,
|
|
||||||
episode: &EpisodeWidgetQuery,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let id = episode.rowid();
|
|
||||||
let active_dl = || -> Result<Option<_>, Error> {
|
|
||||||
let m = manager::ACTIVE_DOWNLOADS
|
|
||||||
.read()
|
|
||||||
.map_err(|_| format_err!("Failed to get a lock on the mutex."))?;
|
|
||||||
|
|
||||||
Ok(m.get(&id).cloned())
|
|
||||||
}()?;
|
|
||||||
|
|
||||||
let mut lock = media_machine.try_borrow_mut()?;
|
|
||||||
take_mut::take(lock.deref_mut(), |media| {
|
|
||||||
media.determine_state(
|
|
||||||
episode.length(),
|
|
||||||
active_dl.is_some(),
|
|
||||||
episode.local_uri().is_some(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show or hide the play/delete/download buttons upon widget initialization.
|
|
||||||
if let Some(prog) = active_dl {
|
|
||||||
// set a callback that will update the state when the download finishes
|
|
||||||
let id = episode.rowid();
|
|
||||||
let callback = clone!(media_machine => move || {
|
|
||||||
if let Ok(guard) = manager::ACTIVE_DOWNLOADS.read() {
|
|
||||||
if !guard.contains_key(&id) {
|
|
||||||
if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
|
||||||
determine_media_state(&media_machine, &ep)
|
|
||||||
.map_err(|err| error!("Error: {}", err))
|
|
||||||
.map_err(|_| error!("Could not determine Media State"))
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
return glib::Continue(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glib::Continue(true)
|
|
||||||
});
|
|
||||||
gtk::timeout_add(250, callback);
|
|
||||||
|
|
||||||
lock.cancel_connect_clicked(clone!(prog, media_machine => move |_| {
|
|
||||||
if let Ok(mut m) = prog.lock() {
|
|
||||||
m.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(mut lock) = media_machine.try_borrow_mut() {
|
|
||||||
if let Ok(episode) = dbqueries::get_episode_widget_from_rowid(id) {
|
|
||||||
take_mut::take(lock.deref_mut(), |media| {
|
|
||||||
media.determine_state(
|
|
||||||
episode.length(),
|
|
||||||
false,
|
|
||||||
episode.local_uri().is_some(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
drop(lock);
|
|
||||||
|
|
||||||
// Setup a callback that will update the progress bar.
|
|
||||||
update_progressbar_callback(&prog, &media_machine, id);
|
|
||||||
|
|
||||||
// Setup a callback that will update the total_size label
|
|
||||||
// with the http ContentLength header number rather than
|
|
||||||
// relying to the RSS feed.
|
|
||||||
update_total_size_callback(&prog, &media_machine);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: &Sender<Action>) -> Result<(), Error> {
|
fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: &Sender<Action>) -> Result<(), Error> {
|
||||||
@@ -241,26 +465,23 @@ fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: &Sender<Action>) -> Resu
|
|||||||
manager::add(ep.rowid(), download_fold)?;
|
manager::add(ep.rowid(), download_fold)?;
|
||||||
|
|
||||||
// Update Views
|
// Update Views
|
||||||
sender.send(Action::RefreshEpisodesViewBGR)?;
|
sender
|
||||||
|
.send(Action::RefreshEpisodesViewBGR)
|
||||||
Ok(())
|
.map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_play_bttn_clicked(
|
fn on_play_bttn_clicked(
|
||||||
|
widget: &Rc<EpisodeWidget>,
|
||||||
episode: &mut EpisodeWidgetQuery,
|
episode: &mut EpisodeWidgetQuery,
|
||||||
title: &Rc<RefCell<TitleMachine>>,
|
|
||||||
sender: &Sender<Action>,
|
sender: &Sender<Action>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
open_uri(episode.rowid())?;
|
open_uri(episode.rowid())?;
|
||||||
episode.set_played_now()?;
|
episode.set_played_now()?;
|
||||||
|
|
||||||
let mut machine = title.try_borrow_mut()?;
|
widget.info.set_title(&episode);
|
||||||
take_mut::take(machine.deref_mut(), |title| {
|
sender
|
||||||
title.determine_state(episode.played().is_some())
|
.send(Action::RefreshEpisodesViewBGR)
|
||||||
});
|
.map_err(From::from)
|
||||||
|
|
||||||
sender.send(Action::RefreshEpisodesViewBGR)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_uri(rowid: i32) -> Result<(), Error> {
|
fn open_uri(rowid: i32) -> Result<(), Error> {
|
||||||
@@ -281,27 +502,27 @@ fn open_uri(rowid: i32) -> Result<(), Error> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[cfg_attr(feature = "cargo-clippy", allow(if_same_then_else))]
|
#[cfg_attr(feature = "cargo-clippy", allow(if_same_then_else))]
|
||||||
fn update_progressbar_callback(
|
fn update_progressbar_callback(
|
||||||
|
widget: &Rc<EpisodeWidget>,
|
||||||
prog: &Arc<Mutex<manager::Progress>>,
|
prog: &Arc<Mutex<manager::Progress>>,
|
||||||
media: &Rc<RefCell<MediaMachine>>,
|
|
||||||
episode_rowid: i32,
|
episode_rowid: i32,
|
||||||
) {
|
) {
|
||||||
let callback = clone!(prog, media => move || {
|
let callback = clone!(widget, prog => move || {
|
||||||
progress_bar_helper(&prog, &media, episode_rowid)
|
progress_bar_helper(&widget, &prog, episode_rowid)
|
||||||
.unwrap_or(glib::Continue(false))
|
.unwrap_or(glib::Continue(false))
|
||||||
});
|
});
|
||||||
timeout_add(300, callback);
|
timeout_add(100, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(if_same_then_else)]
|
#[allow(if_same_then_else)]
|
||||||
fn progress_bar_helper(
|
fn progress_bar_helper(
|
||||||
|
widget: &Rc<EpisodeWidget>,
|
||||||
prog: &Arc<Mutex<manager::Progress>>,
|
prog: &Arc<Mutex<manager::Progress>>,
|
||||||
media: &Rc<RefCell<MediaMachine>>,
|
|
||||||
episode_rowid: i32,
|
episode_rowid: i32,
|
||||||
) -> Result<glib::Continue, Error> {
|
) -> Result<glib::Continue, Error> {
|
||||||
let (fraction, downloaded) = {
|
let (fraction, downloaded) = match prog.try_lock() {
|
||||||
let m = prog.lock()
|
Ok(guard) => (guard.get_fraction(), guard.get_downloaded()),
|
||||||
.map_err(|_| format_err!("Failed to get a lock on the mutex."))?;
|
Err(TryLockError::WouldBlock) => return Ok(glib::Continue(true)),
|
||||||
(m.get_fraction(), m.get_downloaded())
|
Err(TryLockError::Poisoned(_)) => return Err(format_err!("Progress Mutex is poisoned")),
|
||||||
};
|
};
|
||||||
|
|
||||||
// I hate floating points.
|
// I hate floating points.
|
||||||
@@ -312,20 +533,16 @@ fn progress_bar_helper(
|
|||||||
.file_size(SIZE_OPTS.clone())
|
.file_size(SIZE_OPTS.clone())
|
||||||
.map_err(|err| format_err!("{}", err))?;
|
.map_err(|err| format_err!("{}", err))?;
|
||||||
|
|
||||||
if let Ok(mut m) = media.try_borrow_mut() {
|
widget.update_progress(&size, fraction);
|
||||||
m.update_progress(&size, fraction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// info!("Fraction: {}", progress_bar.get_fraction());
|
// info!("Fraction: {}", progress_bar.get_fraction());
|
||||||
// info!("Fraction: {}", fraction);
|
// info!("Fraction: {}", fraction);
|
||||||
|
|
||||||
// Check if the download is still active
|
// Check if the download is still active
|
||||||
let active = {
|
let active = match manager::ACTIVE_DOWNLOADS.read() {
|
||||||
let m = manager::ACTIVE_DOWNLOADS
|
Ok(guard) => guard.contains_key(&episode_rowid),
|
||||||
.read()
|
Err(_) => return Err(format_err!("Failed to get a lock on the mutex.")),
|
||||||
.map_err(|_| format_err!("Failed to get a lock on the mutex."))?;
|
|
||||||
m.contains_key(&episode_rowid)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fraction >= 1.0) && (!fraction.is_nan()) {
|
if (fraction >= 1.0) && (!fraction.is_nan()) {
|
||||||
@@ -341,35 +558,28 @@ fn progress_bar_helper(
|
|||||||
// with the http ContentLength header number rather than
|
// with the http ContentLength header number rather than
|
||||||
// relying to the RSS feed.
|
// relying to the RSS feed.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn update_total_size_callback(
|
fn update_total_size_callback(widget: &Rc<EpisodeWidget>, prog: &Arc<Mutex<manager::Progress>>) {
|
||||||
prog: &Arc<Mutex<manager::Progress>>,
|
let callback = clone!(prog, widget => move || {
|
||||||
media: &Rc<RefCell<MediaMachine>>,
|
total_size_helper(&widget, &prog).unwrap_or(glib::Continue(true))
|
||||||
) {
|
|
||||||
let callback = clone!(prog, media => move || {
|
|
||||||
total_size_helper(&prog, &media).unwrap_or(glib::Continue(true))
|
|
||||||
});
|
});
|
||||||
timeout_add(500, callback);
|
timeout_add(100, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn total_size_helper(
|
fn total_size_helper(
|
||||||
|
widget: &Rc<EpisodeWidget>,
|
||||||
prog: &Arc<Mutex<manager::Progress>>,
|
prog: &Arc<Mutex<manager::Progress>>,
|
||||||
media: &Rc<RefCell<MediaMachine>>,
|
|
||||||
) -> Result<glib::Continue, Error> {
|
) -> Result<glib::Continue, Error> {
|
||||||
// Get the total_bytes.
|
// Get the total_bytes.
|
||||||
let total_bytes = {
|
let total_bytes = match prog.try_lock() {
|
||||||
let m = prog.lock()
|
Ok(guard) => guard.get_total_size(),
|
||||||
.map_err(|_| format_err!("Failed to get a lock on the mutex."))?;
|
Err(TryLockError::WouldBlock) => return Ok(glib::Continue(true)),
|
||||||
m.get_total_size()
|
Err(TryLockError::Poisoned(_)) => return Err(format_err!("Progress Mutex is poisoned")),
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Total Size: {}", total_bytes);
|
debug!("Total Size: {}", total_bytes);
|
||||||
if total_bytes != 0 {
|
if total_bytes != 0 {
|
||||||
// Update the total_size label
|
// Update the total_size label
|
||||||
if let Ok(mut m) = media.try_borrow_mut() {
|
widget.info.set_size(Some(total_bytes as i32));
|
||||||
take_mut::take(m.deref_mut(), |machine| {
|
|
||||||
machine.set_size(Some(total_bytes as i32))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not call again the callback
|
// Do not call again the callback
|
||||||
Ok(glib::Continue(false))
|
Ok(glib::Continue(false))
|
||||||
|
|||||||
@@ -1,879 +0,0 @@
|
|||||||
// TODO: Things that should be done.
|
|
||||||
//
|
|
||||||
// * Wherever there's a function that take 2 or more arguments of the same type,
|
|
||||||
// eg: fn new(total_size: gtk::Label, local_size: gtk::Label ..)
|
|
||||||
// Wrap the types into Struct-tuples and imple deref so it won't be possible to pass
|
|
||||||
// the wrong argument to the wrong position.
|
|
||||||
|
|
||||||
use chrono;
|
|
||||||
use glib;
|
|
||||||
use gtk;
|
|
||||||
|
|
||||||
use chrono::prelude::*;
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use humansize::{file_size_opts as size_opts, FileSize};
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = {
|
|
||||||
// Declare a custom humansize option struct
|
|
||||||
// See: https://docs.rs/humansize/1.0.2/humansize/file_size_opts/struct.FileSizeOpts.html
|
|
||||||
Arc::new(size_opts::FileSizeOpts {
|
|
||||||
divider: size_opts::Kilo::Binary,
|
|
||||||
units: size_opts::Kilo::Decimal,
|
|
||||||
decimal_places: 0,
|
|
||||||
decimal_zeroes: 0,
|
|
||||||
fixed_at: size_opts::FixedAt::No,
|
|
||||||
long_units: false,
|
|
||||||
space: true,
|
|
||||||
suffix: "",
|
|
||||||
allow_negative: false,
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
static ref NOW: DateTime<Utc> = Utc::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct UnInitialized;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Shown;
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Hidden;
|
|
||||||
|
|
||||||
pub trait Visibility {}
|
|
||||||
|
|
||||||
impl Visibility for Shown {}
|
|
||||||
impl Visibility for Hidden {}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Normal;
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct GreyedOut;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Title<S> {
|
|
||||||
title: gtk::Label,
|
|
||||||
state: S,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> Title<S> {
|
|
||||||
#[allow(unused_must_use)]
|
|
||||||
// This does not need to be &mut since gtk-rs does not model ownership
|
|
||||||
// But I think it wouldn't hurt if we treat it as a Rust api.
|
|
||||||
fn set_title(&mut self, s: &str) {
|
|
||||||
self.title.set_text(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Title<Normal> {
|
|
||||||
fn new(title: gtk::Label) -> Self {
|
|
||||||
Title {
|
|
||||||
title,
|
|
||||||
state: Normal {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Title<Normal>> for Title<GreyedOut> {
|
|
||||||
fn from(f: Title<Normal>) -> Self {
|
|
||||||
f.title
|
|
||||||
.get_style_context()
|
|
||||||
.map(|c| c.add_class("dim-label"));
|
|
||||||
|
|
||||||
Title {
|
|
||||||
title: f.title,
|
|
||||||
state: GreyedOut {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Title<GreyedOut>> for Title<Normal> {
|
|
||||||
fn from(f: Title<GreyedOut>) -> Self {
|
|
||||||
f.title
|
|
||||||
.get_style_context()
|
|
||||||
.map(|c| c.remove_class("dim-label"));
|
|
||||||
|
|
||||||
Title {
|
|
||||||
title: f.title,
|
|
||||||
state: Normal {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum TitleMachine {
|
|
||||||
Normal(Title<Normal>),
|
|
||||||
GreyedOut(Title<GreyedOut>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TitleMachine {
|
|
||||||
pub fn new(label: gtk::Label, is_played: bool) -> Self {
|
|
||||||
let m = TitleMachine::Normal(Title::<Normal>::new(label));
|
|
||||||
m.determine_state(is_played)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn determine_state(self, is_played: bool) -> Self {
|
|
||||||
use self::TitleMachine::*;
|
|
||||||
|
|
||||||
match (self, is_played) {
|
|
||||||
(title @ Normal(_), false) => title,
|
|
||||||
(title @ GreyedOut(_), true) => title,
|
|
||||||
(Normal(val), true) => GreyedOut(val.into()),
|
|
||||||
(GreyedOut(val), false) => Normal(val.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_title(&mut self, s: &str) {
|
|
||||||
use self::TitleMachine::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
Normal(ref mut val) => val.set_title(s),
|
|
||||||
GreyedOut(ref mut val) => val.set_title(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Usual;
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct YearShown;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Date<S> {
|
|
||||||
date: gtk::Label,
|
|
||||||
epoch: i64,
|
|
||||||
state: S,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> Date<S> {
|
|
||||||
fn into_usual(self, epoch: i64) -> Date<Usual> {
|
|
||||||
let ts = Utc.timestamp(epoch, 0);
|
|
||||||
self.date.set_text(ts.format("%e %b").to_string().trim());
|
|
||||||
|
|
||||||
Date {
|
|
||||||
date: self.date,
|
|
||||||
epoch: self.epoch,
|
|
||||||
state: Usual {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_year_shown(self, epoch: i64) -> Date<YearShown> {
|
|
||||||
let ts = Utc.timestamp(epoch, 0);
|
|
||||||
self.date.set_text(ts.format("%e %b %Y").to_string().trim());
|
|
||||||
|
|
||||||
Date {
|
|
||||||
date: self.date,
|
|
||||||
epoch: self.epoch,
|
|
||||||
state: YearShown {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Date<UnInitialized> {
|
|
||||||
fn new(date: gtk::Label, epoch: i64) -> Self {
|
|
||||||
let ts = Utc.timestamp(epoch, 0);
|
|
||||||
date.set_text(ts.format("%e %b %Y").to_string().trim());
|
|
||||||
|
|
||||||
Date {
|
|
||||||
date,
|
|
||||||
epoch,
|
|
||||||
state: UnInitialized {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum DateMachine {
|
|
||||||
UnInitialized(Date<UnInitialized>),
|
|
||||||
Usual(Date<Usual>),
|
|
||||||
WithYear(Date<YearShown>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DateMachine {
|
|
||||||
pub fn new(label: gtk::Label, epoch: i64) -> Self {
|
|
||||||
let m = DateMachine::UnInitialized(Date::<UnInitialized>::new(label, epoch));
|
|
||||||
m.determine_state(epoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn determine_state(self, epoch: i64) -> Self {
|
|
||||||
use self::DateMachine::*;
|
|
||||||
|
|
||||||
let ts = Utc.timestamp(epoch, 0);
|
|
||||||
let is_old = NOW.year() != ts.year();
|
|
||||||
|
|
||||||
match (self, is_old) {
|
|
||||||
// Into Usual
|
|
||||||
(Usual(val), false) => Usual(val.into_usual(epoch)),
|
|
||||||
(WithYear(val), false) => Usual(val.into_usual(epoch)),
|
|
||||||
(UnInitialized(val), false) => Usual(val.into_usual(epoch)),
|
|
||||||
|
|
||||||
// Into Year Shown
|
|
||||||
(Usual(val), true) => WithYear(val.into_year_shown(epoch)),
|
|
||||||
(WithYear(val), true) => WithYear(val.into_year_shown(epoch)),
|
|
||||||
(UnInitialized(val), true) => WithYear(val.into_year_shown(epoch)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Duration<S: Visibility> {
|
|
||||||
// TODO: make duration and separator diff types
|
|
||||||
duration: gtk::Label,
|
|
||||||
separator: gtk::Label,
|
|
||||||
state: S,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: Visibility> Duration<S> {
|
|
||||||
// This needs a better name.
|
|
||||||
// TODO: make me mut
|
|
||||||
fn set_duration(&self, minutes: i64) {
|
|
||||||
self.duration.set_text(&format!("{} min", minutes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Duration<Hidden> {
|
|
||||||
fn new(duration: gtk::Label, separator: gtk::Label) -> Self {
|
|
||||||
duration.hide();
|
|
||||||
separator.hide();
|
|
||||||
|
|
||||||
Duration {
|
|
||||||
duration,
|
|
||||||
separator,
|
|
||||||
state: Hidden {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Duration<Hidden>> for Duration<Shown> {
|
|
||||||
fn from(f: Duration<Hidden>) -> Self {
|
|
||||||
f.duration.show();
|
|
||||||
f.separator.show();
|
|
||||||
|
|
||||||
Duration {
|
|
||||||
duration: f.duration,
|
|
||||||
separator: f.separator,
|
|
||||||
state: Shown {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Duration<Shown>> for Duration<Hidden> {
|
|
||||||
fn from(f: Duration<Shown>) -> Self {
|
|
||||||
f.duration.hide();
|
|
||||||
f.separator.hide();
|
|
||||||
|
|
||||||
Duration {
|
|
||||||
duration: f.duration,
|
|
||||||
separator: f.separator,
|
|
||||||
state: Hidden {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum DurationMachine {
|
|
||||||
Hidden(Duration<Hidden>),
|
|
||||||
Shown(Duration<Shown>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DurationMachine {
|
|
||||||
pub fn new(duration: gtk::Label, separator: gtk::Label, seconds: Option<i32>) -> Self {
|
|
||||||
let m = DurationMachine::Hidden(Duration::<Hidden>::new(duration, separator));
|
|
||||||
m.determine_state(seconds)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn determine_state(self, seconds: Option<i32>) -> Self {
|
|
||||||
match (self, seconds) {
|
|
||||||
(d @ DurationMachine::Hidden(_), None) => d,
|
|
||||||
(DurationMachine::Shown(val), None) => DurationMachine::Hidden(val.into()),
|
|
||||||
(DurationMachine::Hidden(val), Some(s)) => {
|
|
||||||
let minutes = chrono::Duration::seconds(s.into()).num_minutes();
|
|
||||||
if minutes == 0 {
|
|
||||||
DurationMachine::Hidden(val)
|
|
||||||
} else {
|
|
||||||
val.set_duration(minutes);
|
|
||||||
DurationMachine::Shown(val.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(DurationMachine::Shown(val), Some(s)) => {
|
|
||||||
let minutes = chrono::Duration::seconds(s.into()).num_minutes();
|
|
||||||
if minutes == 0 {
|
|
||||||
DurationMachine::Hidden(val.into())
|
|
||||||
} else {
|
|
||||||
val.set_duration(minutes);
|
|
||||||
DurationMachine::Shown(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Size<S> {
|
|
||||||
size: gtk::Label,
|
|
||||||
separator: gtk::Label,
|
|
||||||
state: S,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> Size<S> {
|
|
||||||
fn set_size(self, s: &str) -> Size<Shown> {
|
|
||||||
self.size.set_text(s);
|
|
||||||
self.size.show();
|
|
||||||
self.separator.show();
|
|
||||||
Size {
|
|
||||||
size: self.size,
|
|
||||||
separator: self.separator,
|
|
||||||
state: Shown {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://play.rust-lang.org/?gist=1acffaf62743eeb85be1ae6ecf474784&version=stable
|
|
||||||
// It might be possible to make a generic definition with Specialization.
|
|
||||||
// https://github.com/rust-lang/rust/issues/31844
|
|
||||||
fn into_shown(self) -> Size<Shown> {
|
|
||||||
self.size.show();
|
|
||||||
self.separator.show();
|
|
||||||
|
|
||||||
Size {
|
|
||||||
size: self.size,
|
|
||||||
separator: self.separator,
|
|
||||||
state: Shown {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_hidden(self) -> Size<Hidden> {
|
|
||||||
self.size.hide();
|
|
||||||
self.separator.hide();
|
|
||||||
|
|
||||||
Size {
|
|
||||||
size: self.size,
|
|
||||||
separator: self.separator,
|
|
||||||
state: Hidden {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Size<UnInitialized> {
|
|
||||||
fn new(size: gtk::Label, separator: gtk::Label) -> Self {
|
|
||||||
size.hide();
|
|
||||||
separator.hide();
|
|
||||||
|
|
||||||
Size {
|
|
||||||
size,
|
|
||||||
separator,
|
|
||||||
state: UnInitialized {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub trait Playable {}
|
|
||||||
|
|
||||||
// impl Playable for Download {}
|
|
||||||
// impl Playable for Play {}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Download;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Play;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
// FIXME: Needs better name.
|
|
||||||
// Should each button also has it's own type and machine?
|
|
||||||
pub struct DownloadPlay<S> {
|
|
||||||
play: gtk::Button,
|
|
||||||
download: gtk::Button,
|
|
||||||
state: S,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> DownloadPlay<S> {
|
|
||||||
// https://play.rust-lang.org/?gist=1acffaf62743eeb85be1ae6ecf474784&version=stable
|
|
||||||
// It might be possible to make a generic definition with Specialization.
|
|
||||||
// https://github.com/rust-lang/rust/issues/31844
|
|
||||||
fn into_playable(self) -> DownloadPlay<Play> {
|
|
||||||
self.play.show();
|
|
||||||
self.download.hide();
|
|
||||||
|
|
||||||
DownloadPlay {
|
|
||||||
play: self.play,
|
|
||||||
download: self.download,
|
|
||||||
state: Play {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_fetchable(self) -> DownloadPlay<Download> {
|
|
||||||
self.play.hide();
|
|
||||||
self.download.show();
|
|
||||||
|
|
||||||
DownloadPlay {
|
|
||||||
play: self.play,
|
|
||||||
download: self.download,
|
|
||||||
state: Download {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_hidden(self) -> DownloadPlay<Hidden> {
|
|
||||||
self.play.hide();
|
|
||||||
self.download.hide();
|
|
||||||
|
|
||||||
DownloadPlay {
|
|
||||||
play: self.play,
|
|
||||||
download: self.download,
|
|
||||||
state: Hidden {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn download_connect_clicked<F: Fn(>k::Button) + 'static>(
|
|
||||||
&self,
|
|
||||||
f: F,
|
|
||||||
) -> glib::SignalHandlerId {
|
|
||||||
self.download.connect_clicked(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn play_connect_clicked<F: Fn(>k::Button) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
|
||||||
self.play.connect_clicked(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DownloadPlay<UnInitialized> {
|
|
||||||
fn new(play: gtk::Button, download: gtk::Button) -> Self {
|
|
||||||
play.hide();
|
|
||||||
download.hide();
|
|
||||||
|
|
||||||
DownloadPlay {
|
|
||||||
play,
|
|
||||||
download,
|
|
||||||
state: UnInitialized {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Progress<S> {
|
|
||||||
bar: gtk::ProgressBar,
|
|
||||||
cancel: gtk::Button,
|
|
||||||
local_size: gtk::Label,
|
|
||||||
prog_separator: gtk::Label,
|
|
||||||
state: S,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> Progress<S> {
|
|
||||||
fn into_shown(self) -> Progress<Shown> {
|
|
||||||
self.bar.show();
|
|
||||||
self.cancel.show();
|
|
||||||
self.local_size.show();
|
|
||||||
self.prog_separator.show();
|
|
||||||
|
|
||||||
Progress {
|
|
||||||
bar: self.bar,
|
|
||||||
cancel: self.cancel,
|
|
||||||
local_size: self.local_size,
|
|
||||||
prog_separator: self.prog_separator,
|
|
||||||
state: Shown {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_hidden(self) -> Progress<Hidden> {
|
|
||||||
self.bar.hide();
|
|
||||||
self.cancel.hide();
|
|
||||||
self.local_size.hide();
|
|
||||||
self.prog_separator.hide();
|
|
||||||
|
|
||||||
Progress {
|
|
||||||
bar: self.bar,
|
|
||||||
cancel: self.cancel,
|
|
||||||
local_size: self.local_size,
|
|
||||||
prog_separator: self.prog_separator,
|
|
||||||
state: Hidden {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_must_use)]
|
|
||||||
// This does not need to be &mut since gtk-rs does not model ownership
|
|
||||||
// But I think it wouldn't hurt if we treat it as a Rust api.
|
|
||||||
fn update_progress(&mut self, local_size: &str, fraction: f64) {
|
|
||||||
self.local_size.set_text(local_size);
|
|
||||||
self.bar.set_fraction(fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cancel_connect_clicked<F: Fn(>k::Button) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
|
||||||
self.cancel.connect_clicked(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Progress<UnInitialized> {
|
|
||||||
fn new(
|
|
||||||
bar: gtk::ProgressBar,
|
|
||||||
cancel: gtk::Button,
|
|
||||||
local_size: gtk::Label,
|
|
||||||
prog_separator: gtk::Label,
|
|
||||||
) -> Self {
|
|
||||||
bar.hide();
|
|
||||||
cancel.hide();
|
|
||||||
local_size.hide();
|
|
||||||
prog_separator.hide();
|
|
||||||
|
|
||||||
Progress {
|
|
||||||
bar,
|
|
||||||
cancel,
|
|
||||||
local_size,
|
|
||||||
prog_separator,
|
|
||||||
state: UnInitialized {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Media<X, Y, Z> {
|
|
||||||
dl: DownloadPlay<X>,
|
|
||||||
size: Size<Y>,
|
|
||||||
progress: Progress<Z>,
|
|
||||||
}
|
|
||||||
|
|
||||||
type New<Y> = Media<Download, Y, Hidden>;
|
|
||||||
type Playable<Y> = Media<Play, Y, Hidden>;
|
|
||||||
type InProgress = Media<Hidden, Shown, Shown>;
|
|
||||||
|
|
||||||
impl<X, Y, Z> Media<X, Y, Z> {
|
|
||||||
fn set_size(self, s: &str) -> Media<X, Shown, Z> {
|
|
||||||
Media {
|
|
||||||
dl: self.dl,
|
|
||||||
size: self.size.set_size(s),
|
|
||||||
progress: self.progress,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hide_size(self) -> Media<X, Hidden, Z> {
|
|
||||||
Media {
|
|
||||||
dl: self.dl,
|
|
||||||
size: self.size.into_hidden(),
|
|
||||||
progress: self.progress,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_new(self, size: &str) -> New<Shown> {
|
|
||||||
Media {
|
|
||||||
dl: self.dl.into_fetchable(),
|
|
||||||
size: self.size.set_size(size),
|
|
||||||
progress: self.progress.into_hidden(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_new_without(self) -> New<Hidden> {
|
|
||||||
Media {
|
|
||||||
dl: self.dl.into_fetchable(),
|
|
||||||
size: self.size.into_hidden(),
|
|
||||||
progress: self.progress.into_hidden(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_playable(self, size: &str) -> Playable<Shown> {
|
|
||||||
Media {
|
|
||||||
dl: self.dl.into_playable(),
|
|
||||||
size: self.size.set_size(size),
|
|
||||||
progress: self.progress.into_hidden(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_playable_without(self) -> Playable<Hidden> {
|
|
||||||
Media {
|
|
||||||
dl: self.dl.into_playable(),
|
|
||||||
size: self.size.into_hidden(),
|
|
||||||
progress: self.progress.into_hidden(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<X, Z> Media<X, Shown, Z> {
|
|
||||||
fn into_progress(self) -> InProgress {
|
|
||||||
Media {
|
|
||||||
dl: self.dl.into_hidden(),
|
|
||||||
size: self.size.into_shown(),
|
|
||||||
progress: self.progress.into_shown(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<X, Z> Media<X, Hidden, Z> {
|
|
||||||
fn into_progress(self) -> InProgress {
|
|
||||||
Media {
|
|
||||||
dl: self.dl.into_hidden(),
|
|
||||||
size: self.size.set_size("Unkown"),
|
|
||||||
progress: self.progress.into_shown(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<X, Z> Media<X, UnInitialized, Z> {
|
|
||||||
fn into_progress(self, size: Option<String>) -> InProgress {
|
|
||||||
if let Some(s) = size {
|
|
||||||
Media {
|
|
||||||
dl: self.dl.into_hidden(),
|
|
||||||
size: self.size.set_size(&s),
|
|
||||||
progress: self.progress.into_shown(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Media {
|
|
||||||
dl: self.dl.into_hidden(),
|
|
||||||
size: self.size.set_size("Unkown"),
|
|
||||||
progress: self.progress.into_shown(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InProgress {
|
|
||||||
#[allow(unused_must_use)]
|
|
||||||
// This does not need to be &mut since gtk-rs does not model ownership
|
|
||||||
// But I think it wouldn't hurt if we treat it as a Rust api.
|
|
||||||
fn update_progress(&mut self, local_size: &str, fraction: f64) {
|
|
||||||
self.progress.update_progress(local_size, fraction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum ButtonsState {
|
|
||||||
New(Media<Download, Shown, Hidden>),
|
|
||||||
NewWithoutSize(Media<Download, Hidden, Hidden>),
|
|
||||||
Playable(Media<Play, Shown, Hidden>),
|
|
||||||
PlayableWithoutSize(Media<Play, Hidden, Hidden>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ButtonsState {
|
|
||||||
pub fn determine_state(self, size: Option<String>, is_downloaded: bool) -> Self {
|
|
||||||
use self::ButtonsState::*;
|
|
||||||
|
|
||||||
match (self, size, is_downloaded) {
|
|
||||||
// From whatever to New
|
|
||||||
(New(m), Some(s), false) => New(m.into_new(&s)),
|
|
||||||
(Playable(m), Some(s), false) => New(m.into_new(&s)),
|
|
||||||
|
|
||||||
(NewWithoutSize(m), Some(s), false) => New(m.into_new(&s)),
|
|
||||||
(PlayableWithoutSize(m), Some(s), false) => New(m.into_new(&s)),
|
|
||||||
|
|
||||||
// From whatever to Playable
|
|
||||||
(New(m), Some(s), true) => Playable(m.into_playable(&s)),
|
|
||||||
(Playable(m), Some(s), true) => Playable(m.into_playable(&s)),
|
|
||||||
|
|
||||||
(NewWithoutSize(m), Some(s), true) => Playable(m.into_playable(&s)),
|
|
||||||
(PlayableWithoutSize(m), Some(s), true) => Playable(m.into_playable(&s)),
|
|
||||||
|
|
||||||
// From whatever to NewWithoutSize
|
|
||||||
(New(m), None, false) => NewWithoutSize(m.hide_size()),
|
|
||||||
(Playable(m), None, false) => NewWithoutSize(m.into_new_without()),
|
|
||||||
|
|
||||||
(b @ NewWithoutSize(_), None, false) => b,
|
|
||||||
(PlayableWithoutSize(m), None, false) => NewWithoutSize(m.into_new_without()),
|
|
||||||
|
|
||||||
// From whatever to PlayableWithoutSize
|
|
||||||
(New(m), None, true) => PlayableWithoutSize(m.into_playable_without()),
|
|
||||||
(Playable(m), None, true) => PlayableWithoutSize(m.hide_size()),
|
|
||||||
|
|
||||||
(NewWithoutSize(val), None, true) => PlayableWithoutSize(val.into_playable_without()),
|
|
||||||
(b @ PlayableWithoutSize(_), None, true) => b,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_progress(self) -> InProgress {
|
|
||||||
use self::ButtonsState::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
New(m) => m.into_progress(),
|
|
||||||
Playable(m) => m.into_progress(),
|
|
||||||
NewWithoutSize(m) => m.into_progress(),
|
|
||||||
PlayableWithoutSize(m) => m.into_progress(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_size(self, size: Option<String>) -> Self {
|
|
||||||
use self::ButtonsState::*;
|
|
||||||
|
|
||||||
match (self, size) {
|
|
||||||
(New(m), Some(s)) => New(m.set_size(&s)),
|
|
||||||
(New(m), None) => NewWithoutSize(m.hide_size()),
|
|
||||||
(Playable(m), Some(s)) => Playable(m.set_size(&s)),
|
|
||||||
(Playable(m), None) => PlayableWithoutSize(m.hide_size()),
|
|
||||||
(bttn @ NewWithoutSize(_), None) => bttn,
|
|
||||||
(bttn @ PlayableWithoutSize(_), None) => bttn,
|
|
||||||
(NewWithoutSize(m), Some(s)) => New(m.into_new(&s)),
|
|
||||||
(PlayableWithoutSize(m), Some(s)) => Playable(m.into_playable(&s)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn download_connect_clicked<F: Fn(>k::Button) + 'static>(
|
|
||||||
&self,
|
|
||||||
f: F,
|
|
||||||
) -> glib::SignalHandlerId {
|
|
||||||
use self::ButtonsState::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
New(ref val) => val.dl.download_connect_clicked(f),
|
|
||||||
NewWithoutSize(ref val) => val.dl.download_connect_clicked(f),
|
|
||||||
Playable(ref val) => val.dl.download_connect_clicked(f),
|
|
||||||
PlayableWithoutSize(ref val) => val.dl.download_connect_clicked(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn play_connect_clicked<F: Fn(>k::Button) + 'static>(
|
|
||||||
&self,
|
|
||||||
f: F,
|
|
||||||
) -> glib::SignalHandlerId {
|
|
||||||
use self::ButtonsState::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
New(ref val) => val.dl.play_connect_clicked(f),
|
|
||||||
NewWithoutSize(ref val) => val.dl.play_connect_clicked(f),
|
|
||||||
Playable(ref val) => val.dl.play_connect_clicked(f),
|
|
||||||
PlayableWithoutSize(ref val) => val.dl.play_connect_clicked(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cancel_connect_clicked<F: Fn(>k::Button) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
|
||||||
use self::ButtonsState::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
New(ref val) => val.progress.cancel_connect_clicked(f),
|
|
||||||
NewWithoutSize(ref val) => val.progress.cancel_connect_clicked(f),
|
|
||||||
Playable(ref val) => val.progress.cancel_connect_clicked(f),
|
|
||||||
PlayableWithoutSize(ref val) => val.progress.cancel_connect_clicked(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum MediaMachine {
|
|
||||||
UnInitialized(Media<UnInitialized, UnInitialized, UnInitialized>),
|
|
||||||
Initialized(ButtonsState),
|
|
||||||
InProgress(Media<Hidden, Shown, Shown>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MediaMachine {
|
|
||||||
#[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
|
|
||||||
pub fn new(
|
|
||||||
play: gtk::Button,
|
|
||||||
download: gtk::Button,
|
|
||||||
bar: gtk::ProgressBar,
|
|
||||||
cancel: gtk::Button,
|
|
||||||
total_size: gtk::Label,
|
|
||||||
local_size: gtk::Label,
|
|
||||||
separator: gtk::Label,
|
|
||||||
prog_separator: gtk::Label,
|
|
||||||
) -> Self {
|
|
||||||
let dl = DownloadPlay::<UnInitialized>::new(play, download);
|
|
||||||
let progress = Progress::<UnInitialized>::new(bar, cancel, local_size, prog_separator);
|
|
||||||
let size = Size::<UnInitialized>::new(total_size, separator);
|
|
||||||
|
|
||||||
MediaMachine::UnInitialized(Media { dl, progress, size })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn download_connect_clicked<F: Fn(>k::Button) + 'static>(
|
|
||||||
&self,
|
|
||||||
f: F,
|
|
||||||
) -> glib::SignalHandlerId {
|
|
||||||
use self::MediaMachine::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
UnInitialized(ref val) => val.dl.download_connect_clicked(f),
|
|
||||||
Initialized(ref val) => val.download_connect_clicked(f),
|
|
||||||
InProgress(ref val) => val.dl.download_connect_clicked(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn play_connect_clicked<F: Fn(>k::Button) + 'static>(
|
|
||||||
&self,
|
|
||||||
f: F,
|
|
||||||
) -> glib::SignalHandlerId {
|
|
||||||
use self::MediaMachine::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
UnInitialized(ref val) => val.dl.play_connect_clicked(f),
|
|
||||||
Initialized(ref val) => val.play_connect_clicked(f),
|
|
||||||
InProgress(ref val) => val.dl.play_connect_clicked(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cancel_connect_clicked<F: Fn(>k::Button) + 'static>(
|
|
||||||
&self,
|
|
||||||
f: F,
|
|
||||||
) -> glib::SignalHandlerId {
|
|
||||||
use self::MediaMachine::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
UnInitialized(ref val) => val.progress.cancel_connect_clicked(f),
|
|
||||||
Initialized(ref val) => val.cancel_connect_clicked(f),
|
|
||||||
InProgress(ref val) => val.progress.cancel_connect_clicked(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn determine_state(self, bytes: Option<i32>, is_active: bool, is_downloaded: bool) -> Self {
|
|
||||||
use self::ButtonsState::*;
|
|
||||||
use self::MediaMachine::*;
|
|
||||||
|
|
||||||
match (self, size_helper(bytes), is_downloaded, is_active) {
|
|
||||||
(UnInitialized(m), s, _, true) => InProgress(m.into_progress(s)),
|
|
||||||
|
|
||||||
// Into New
|
|
||||||
(UnInitialized(m), Some(s), false, false) => Initialized(New(m.into_new(&s))),
|
|
||||||
(UnInitialized(m), None, false, false) => {
|
|
||||||
Initialized(NewWithoutSize(m.into_new_without()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Into Playable
|
|
||||||
(UnInitialized(m), Some(s), true, false) => Initialized(Playable(m.into_playable(&s))),
|
|
||||||
(UnInitialized(m), None, true, false) => {
|
|
||||||
Initialized(PlayableWithoutSize(m.into_playable_without()))
|
|
||||||
}
|
|
||||||
|
|
||||||
(Initialized(bttn), s, dl, false) => Initialized(bttn.determine_state(s, dl)),
|
|
||||||
(Initialized(bttn), _, _, true) => InProgress(bttn.into_progress()),
|
|
||||||
|
|
||||||
// Into New
|
|
||||||
(InProgress(m), Some(s), false, false) => Initialized(New(m.into_new(&s))),
|
|
||||||
(InProgress(m), None, false, false) => {
|
|
||||||
Initialized(NewWithoutSize(m.into_new_without()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Into Playable
|
|
||||||
(InProgress(m), Some(s), true, false) => Initialized(Playable(m.into_playable(&s))),
|
|
||||||
(InProgress(m), None, true, false) => {
|
|
||||||
Initialized(PlayableWithoutSize(m.into_playable_without()))
|
|
||||||
}
|
|
||||||
|
|
||||||
(i @ InProgress(_), _, _, _) => i,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_size(self, bytes: Option<i32>) -> Self {
|
|
||||||
use self::MediaMachine::*;
|
|
||||||
let size = size_helper(bytes);
|
|
||||||
|
|
||||||
match (self, size) {
|
|
||||||
(Initialized(bttn), s) => Initialized(bttn.set_size(s)),
|
|
||||||
(InProgress(val), Some(s)) => InProgress(val.set_size(&s)),
|
|
||||||
(n @ InProgress(_), None) => n,
|
|
||||||
(n @ UnInitialized(_), _) => n,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_progress(&mut self, local_size: &str, fraction: f64) {
|
|
||||||
use self::MediaMachine::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
Initialized(_) => (),
|
|
||||||
UnInitialized(_) => (),
|
|
||||||
InProgress(ref mut val) => val.update_progress(local_size, fraction),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_helper(bytes: Option<i32>) -> Option<String> {
|
|
||||||
let s = bytes?;
|
|
||||||
if s == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
s.file_size(SIZE_OPTS.clone()).ok()
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@ use failure::Error;
|
|||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use hammond_data::dbqueries;
|
use hammond_data::dbqueries;
|
||||||
use hammond_data::EpisodeWidgetQuery;
|
use hammond_data::EpisodeWidgetQuery;
|
||||||
use send_cell::SendCell;
|
use send_cell::SendCell;
|
||||||
@@ -13,7 +14,6 @@ use utils::{self, lazy_load_full};
|
|||||||
use widgets::EpisodeWidget;
|
use widgets::EpisodeWidget;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@@ -49,7 +49,7 @@ pub struct HomeView {
|
|||||||
|
|
||||||
impl Default for HomeView {
|
impl Default for HomeView {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/episodes_view.ui");
|
||||||
let container: gtk::Box = builder.get_object("container").unwrap();
|
let container: gtk::Box = builder.get_object("container").unwrap();
|
||||||
let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap();
|
let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap();
|
||||||
let frame_parent: gtk::Box = builder.get_object("frame_parent").unwrap();
|
let frame_parent: gtk::Box = builder.get_object("frame_parent").unwrap();
|
||||||
@@ -95,7 +95,7 @@ impl HomeView {
|
|||||||
let view_ = view.clone();
|
let view_ = view.clone();
|
||||||
let func = move |ep: EpisodeWidgetQuery| {
|
let func = move |ep: EpisodeWidgetQuery| {
|
||||||
let epoch = ep.epoch();
|
let epoch = ep.epoch();
|
||||||
let widget = HomeEpisode::new(ep, &sender);
|
let widget = HomeEpisode::new(&ep, &sender);
|
||||||
|
|
||||||
match split(&now_utc, i64::from(epoch)) {
|
match split(&now_utc, i64::from(epoch)) {
|
||||||
Today => add_to_box(&widget, &view_.today_list, &view_.today_box),
|
Today => add_to_box(&widget, &view_.today_list, &view_.today_box),
|
||||||
@@ -138,7 +138,8 @@ impl HomeView {
|
|||||||
/// Save the vertical scrollbar position.
|
/// Save the vertical scrollbar position.
|
||||||
pub fn save_alignment(&self) -> Result<(), Error> {
|
pub fn save_alignment(&self) -> Result<(), Error> {
|
||||||
if let Ok(mut guard) = EPISODES_VIEW_VALIGNMENT.lock() {
|
if let Ok(mut guard) = EPISODES_VIEW_VALIGNMENT.lock() {
|
||||||
let adj = self.scrolled_window
|
let adj = self
|
||||||
|
.scrolled_window
|
||||||
.get_vadjustment()
|
.get_vadjustment()
|
||||||
.ok_or_else(|| format_err!("Could not get the adjustment"))?;
|
.ok_or_else(|| format_err!("Could not get the adjustment"))?;
|
||||||
*guard = Some(SendCell::new(adj));
|
*guard = Some(SendCell::new(adj));
|
||||||
@@ -174,13 +175,14 @@ fn split(now: &DateTime<Utc>, epoch: i64) -> ListSplit {
|
|||||||
struct HomeEpisode {
|
struct HomeEpisode {
|
||||||
container: gtk::Box,
|
container: gtk::Box,
|
||||||
image: gtk::Image,
|
image: gtk::Image,
|
||||||
|
// FIXME: Change it to `EpisodeWidget` instead of a `Box`?
|
||||||
episode: gtk::Box,
|
episode: gtk::Box,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for HomeEpisode {
|
impl Default for HomeEpisode {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let builder =
|
let builder =
|
||||||
gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui");
|
gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/episodes_view_widget.ui");
|
||||||
let container: gtk::Box = builder.get_object("container").unwrap();
|
let container: gtk::Box = builder.get_object("container").unwrap();
|
||||||
let image: gtk::Image = builder.get_object("cover").unwrap();
|
let image: gtk::Image = builder.get_object("cover").unwrap();
|
||||||
let ep = EpisodeWidget::default();
|
let ep = EpisodeWidget::default();
|
||||||
@@ -195,9 +197,9 @@ impl Default for HomeEpisode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HomeEpisode {
|
impl HomeEpisode {
|
||||||
fn new(episode: EpisodeWidgetQuery, sender: &Sender<Action>) -> HomeEpisode {
|
fn new(episode: &EpisodeWidgetQuery, sender: &Sender<Action>) -> HomeEpisode {
|
||||||
let builder =
|
let builder =
|
||||||
gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui");
|
gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/episodes_view_widget.ui");
|
||||||
let container: gtk::Box = builder.get_object("container").unwrap();
|
let container: gtk::Box = builder.get_object("container").unwrap();
|
||||||
let image: gtk::Image = builder.get_object("cover").unwrap();
|
let image: gtk::Image = builder.get_object("cover").unwrap();
|
||||||
let pid = episode.podcast_id();
|
let pid = episode.podcast_id();
|
||||||
@@ -206,7 +208,7 @@ impl HomeEpisode {
|
|||||||
let view = HomeEpisode {
|
let view = HomeEpisode {
|
||||||
container,
|
container,
|
||||||
image,
|
image,
|
||||||
episode: ep.container,
|
episode: ep.container.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
view.init(pid);
|
view.init(pid);
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
|
mod aboutdialog;
|
||||||
|
pub mod appnotif;
|
||||||
mod empty;
|
mod empty;
|
||||||
mod episode;
|
mod episode;
|
||||||
mod episode_states;
|
|
||||||
mod home_view;
|
mod home_view;
|
||||||
mod show;
|
mod show;
|
||||||
mod shows_view;
|
mod shows_view;
|
||||||
|
|
||||||
|
pub use self::aboutdialog::about_dialog;
|
||||||
pub use self::empty::EmptyView;
|
pub use self::empty::EmptyView;
|
||||||
pub use self::episode::EpisodeWidget;
|
pub use self::episode::EpisodeWidget;
|
||||||
pub use self::home_view::HomeView;
|
pub use self::home_view::HomeView;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use glib;
|
|||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
use crossbeam_channel::{SendError, Sender};
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use html2pango::markup_from_raw;
|
use html2pango::markup_from_raw;
|
||||||
use open;
|
use open;
|
||||||
@@ -13,12 +14,11 @@ use hammond_data::utils::delete_show;
|
|||||||
use hammond_data::Podcast;
|
use hammond_data::Podcast;
|
||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
use appnotif::{InAppNotification, UndoState};
|
|
||||||
use utils::{self, lazy_load};
|
use utils::{self, lazy_load};
|
||||||
|
use widgets::appnotif::{InAppNotification, UndoState};
|
||||||
use widgets::EpisodeWidget;
|
use widgets::EpisodeWidget;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::{SendError, Sender};
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@@ -41,7 +41,7 @@ pub struct ShowWidget {
|
|||||||
|
|
||||||
impl Default for ShowWidget {
|
impl Default for ShowWidget {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/show_widget.ui");
|
||||||
let container: gtk::Box = builder.get_object("container").unwrap();
|
let container: gtk::Box = builder.get_object("container").unwrap();
|
||||||
let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap();
|
let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap();
|
||||||
let episodes = builder.get_object("episodes").unwrap();
|
let episodes = builder.get_object("episodes").unwrap();
|
||||||
@@ -79,7 +79,7 @@ impl ShowWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&mut self, pd: &Arc<Podcast>, sender: &Sender<Action>) {
|
pub fn init(&mut self, pd: &Arc<Podcast>, sender: &Sender<Action>) {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/show_widget.ui");
|
||||||
|
|
||||||
self.unsub
|
self.unsub
|
||||||
.connect_clicked(clone!(pd, sender => move |bttn| {
|
.connect_clicked(clone!(pd, sender => move |bttn| {
|
||||||
@@ -130,7 +130,8 @@ impl ShowWidget {
|
|||||||
/// Save the scrollabar vajustment to the cache.
|
/// Save the scrollabar vajustment to the cache.
|
||||||
pub fn save_vadjustment(&self, oldid: i32) -> Result<(), Error> {
|
pub fn save_vadjustment(&self, oldid: i32) -> Result<(), Error> {
|
||||||
if let Ok(mut guard) = SHOW_WIDGET_VALIGNMENT.lock() {
|
if let Ok(mut guard) = SHOW_WIDGET_VALIGNMENT.lock() {
|
||||||
let adj = self.scrolled_window
|
let adj = self
|
||||||
|
.scrolled_window
|
||||||
.get_vadjustment()
|
.get_vadjustment()
|
||||||
.ok_or_else(|| format_err!("Could not get the adjustment"))?;
|
.ok_or_else(|| format_err!("Could not get the adjustment"))?;
|
||||||
*guard = Some((oldid, SendCell::new(adj)));
|
*guard = Some((oldid, SendCell::new(adj)));
|
||||||
@@ -189,7 +190,7 @@ fn populate_listbox(
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_show.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/empty_show.ui");
|
||||||
let container: gtk::Box = builder.get_object("empty_show").unwrap();
|
let container: gtk::Box = builder.get_object("empty_show").unwrap();
|
||||||
show.episodes.add(&container);
|
show.episodes.add(&container);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -206,7 +207,7 @@ fn populate_listbox(
|
|||||||
let list = show_.episodes.clone();
|
let list = show_.episodes.clone();
|
||||||
|
|
||||||
let constructor = clone!(sender => move |ep| {
|
let constructor = clone!(sender => move |ep| {
|
||||||
EpisodeWidget::new(ep, &sender).container
|
EpisodeWidget::new(&ep, &sender).container.clone()
|
||||||
});
|
});
|
||||||
|
|
||||||
let callback = clone!(pd, show_ => move || {
|
let callback = clone!(pd, show_ => move || {
|
||||||
@@ -338,8 +339,7 @@ fn dim_titles(episodes: >k::ListBox) -> Option<()> {
|
|||||||
.downcast::<gtk::Box>()
|
.downcast::<gtk::Box>()
|
||||||
.ok()?;
|
.ok()?;
|
||||||
let bar = foo.get_children().remove(0).downcast::<gtk::Box>().ok()?;
|
let bar = foo.get_children().remove(0).downcast::<gtk::Box>().ok()?;
|
||||||
let baz = bar.get_children().remove(0).downcast::<gtk::Box>().ok()?;
|
let title = bar.get_children().remove(0).downcast::<gtk::Label>().ok()?;
|
||||||
let title = baz.get_children().remove(0).downcast::<gtk::Label>().ok()?;
|
|
||||||
|
|
||||||
title.get_style_context().map(|c| c.add_class("dim-label"));
|
title.get_style_context().map(|c| c.add_class("dim-label"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use send_cell::SendCell;
|
use send_cell::SendCell;
|
||||||
|
|
||||||
@@ -11,7 +12,6 @@ use app::Action;
|
|||||||
use utils::{self, get_ignored_shows, lazy_load, set_image_from_path};
|
use utils::{self, get_ignored_shows, lazy_load, set_image_from_path};
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ pub struct ShowsView {
|
|||||||
|
|
||||||
impl Default for ShowsView {
|
impl Default for ShowsView {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/shows_view.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/shows_view.ui");
|
||||||
let container: gtk::Box = builder.get_object("fb_parent").unwrap();
|
let container: gtk::Box = builder.get_object("fb_parent").unwrap();
|
||||||
let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap();
|
let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap();
|
||||||
let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap();
|
let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap();
|
||||||
@@ -78,7 +78,8 @@ impl ShowsView {
|
|||||||
/// Save the vertical scrollbar position.
|
/// Save the vertical scrollbar position.
|
||||||
pub fn save_alignment(&self) -> Result<(), Error> {
|
pub fn save_alignment(&self) -> Result<(), Error> {
|
||||||
if let Ok(mut guard) = SHOWS_VIEW_VALIGNMENT.lock() {
|
if let Ok(mut guard) = SHOWS_VIEW_VALIGNMENT.lock() {
|
||||||
let adj = self.scrolled_window
|
let adj = self
|
||||||
|
.scrolled_window
|
||||||
.get_vadjustment()
|
.get_vadjustment()
|
||||||
.ok_or_else(|| format_err!("Could not get the adjustment"))?;
|
.ok_or_else(|| format_err!("Could not get the adjustment"))?;
|
||||||
*guard = Some(SendCell::new(adj));
|
*guard = Some(SendCell::new(adj));
|
||||||
@@ -129,7 +130,7 @@ struct ShowsChild {
|
|||||||
|
|
||||||
impl Default for ShowsChild {
|
impl Default for ShowsChild {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/shows_child.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/shows_child.ui");
|
||||||
|
|
||||||
let container: gtk::Box = builder.get_object("fb_child").unwrap();
|
let container: gtk::Box = builder.get_object("fb_child").unwrap();
|
||||||
let cover: gtk::Image = builder.get_object("pd_cover").unwrap();
|
let cover: gtk::Image = builder.get_object("pd_cover").unwrap();
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
project(
|
project(
|
||||||
'hammond', 'rust',
|
'hammond', 'rust',
|
||||||
version: '0.3.3',
|
version: '0.3.4',
|
||||||
license: 'GPLv3',
|
license: 'GPLv3',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"app-id" : "org.gnome.Hammond",
|
"app-id" : "org.gnome.Hammond",
|
||||||
"runtime" : "org.gnome.Platform",
|
"runtime" : "org.gnome.Platform",
|
||||||
"runtime-version" : "master",
|
"runtime-version" : "3.28",
|
||||||
"sdk" : "org.gnome.Sdk",
|
"sdk" : "org.gnome.Sdk",
|
||||||
"sdk-extensions" : [
|
"sdk-extensions" : [
|
||||||
"org.freedesktop.Sdk.Extension.rust-stable"
|
"org.freedesktop.Sdk.Extension.rust-stable"
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"env" : {
|
"env" : {
|
||||||
"CARGO_HOME" : "/run/build/Hammond/cargo",
|
"CARGO_HOME" : "/run/build/Hammond/cargo",
|
||||||
"RUST_BACKTRACE" : "1",
|
"RUST_BACKTRACE" : "1",
|
||||||
"RUSTFLAGS" : "--cfg rayon_unstable"
|
"DEBUG" : "true"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"modules" : [
|
"modules" : [
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
unstable_features = true
|
unstable_features = true
|
||||||
verbose = false
|
|
||||||
max_width = 100
|
max_width = 100
|
||||||
comment_width = 100
|
comment_width = 100
|
||||||
wrap_comments = true
|
wrap_comments = true
|
||||||
tab_spaces = 4
|
tab_spaces = 4
|
||||||
hard_tabs = false
|
hard_tabs = false
|
||||||
newline_style = "Unix"
|
newline_style = "Unix"
|
||||||
write_mode = "Overwrite"
|
|
||||||
condense_wildcard_suffixes = false
|
condense_wildcard_suffixes = false
|
||||||
format_strings = true
|
format_strings = true
|
||||||
normalize_comments = true
|
normalize_comments = true
|
||||||
|
|||||||
+8
-1
@@ -3,4 +3,11 @@
|
|||||||
export CARGO_HOME=$1/target/cargo-home
|
export CARGO_HOME=$1/target/cargo-home
|
||||||
export RUSTFLAGS="--cfg rayon_unstable"
|
export RUSTFLAGS="--cfg rayon_unstable"
|
||||||
|
|
||||||
cargo build --release -p hammond-gtk && cp $1/target/release/hammond-gtk $2
|
if [[ $DEBUG = true ]]
|
||||||
|
then
|
||||||
|
echo "DEBUG MODE"
|
||||||
|
cargo build -p hammond-gtk && cp $1/target/debug/hammond-gtk $2
|
||||||
|
else
|
||||||
|
echo "RELEASE MODE"
|
||||||
|
cargo build --release -p hammond-gtk && cp $1/target/release/hammond-gtk $2
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user