4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/target
|
||||||
|
.idea
|
||||||
|
pkg
|
||||||
|
*.pkg.tar.xz
|
406
Cargo.lock
generated
Normal file
406
Cargo.lock
generated
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alphanumeric-sort"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22b991f3d9c054bb99ed18f24e906b89ec3bc450e788d4911b2b9e123ab3109b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "awatch"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"alphanumeric-sort",
|
||||||
|
"failure",
|
||||||
|
"failure_derive",
|
||||||
|
"lazy_static",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"structopt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.46"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace-sys",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"rustc-demangle",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace-sys"
|
||||||
|
version = "0.1.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "2.33.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||||
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
|
"atty",
|
||||||
|
"bitflags",
|
||||||
|
"strsim",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
"vec_map",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "failure"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"failure_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "failure_derive"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.68"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"syn-mid",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8900ebc1363efa7ea1c399ccc32daed870b4002651e0bed86e72d501ebbe0048"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
"thread_local",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.48"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structopt"
|
||||||
|
version = "0.3.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8faa2719539bbe9d77869bfb15d4ee769f99525e707931452c97b693b3f159d"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"lazy_static",
|
||||||
|
"structopt-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structopt-derive"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn-mid"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "synstructure"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
18
Cargo.toml
Normal file
18
Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[package]
|
||||||
|
name = "awatch"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Pavel Kirilin <win10@list.ru>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
structopt = "0.3" # Used to build CLI.
|
||||||
|
serde = "1.0" # A generic serialization/deserialization framework.
|
||||||
|
serde_derive = "1.0.105" # Used to configure json config stucture.
|
||||||
|
serde_json = "1.0" # Used to store config.
|
||||||
|
failure = "0.1.7" # Experimental error handling abstraction.
|
||||||
|
failure_derive = "0.1.7" # Used to create new error type.
|
||||||
|
lazy_static = "1.4" # Define lazy static vars.
|
||||||
|
alphanumeric-sort = "1.0.12" # Used to search for videos.
|
||||||
|
regex = "1" # Regular expressions.
|
25
PKGBUILD
Normal file
25
PKGBUILD
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Maintainer: s3rius <win10@list.com>
|
||||||
|
pkgname=awatch
|
||||||
|
pkgver=0.1.0
|
||||||
|
pkgrel=2
|
||||||
|
pkgdesc="Anime watcher."
|
||||||
|
arch=('i686' 'x86_64' 'arm' 'armv7h' 'armv6h' 'aarch64')
|
||||||
|
url="https://gitlab.le-memese.com/s3rius/awatch"
|
||||||
|
license=('GPL')
|
||||||
|
options=(!emptydirs)
|
||||||
|
depends=()
|
||||||
|
makedepends=(
|
||||||
|
'rust'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd "$startdir/"
|
||||||
|
pwd
|
||||||
|
cargo build --release
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
mkdir -p "$pkgdir/usr/bin"
|
||||||
|
cp "$startdir/target/release/awatch" "$pkgdir/usr/bin"
|
||||||
|
}
|
48
src/cli.rs
Normal file
48
src/cli.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#[derive(Debug, StructOpt)]
|
||||||
|
#[structopt(
|
||||||
|
name = "awatch",
|
||||||
|
about = "Here to help you with watching anime on your PC."
|
||||||
|
)]
|
||||||
|
pub struct Opt {
|
||||||
|
#[structopt(subcommand)]
|
||||||
|
pub mode: Option<RunMode>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(StructOpt, Debug)]
|
||||||
|
pub enum RunMode {
|
||||||
|
#[structopt(name = "init", about = "Initialize config")]
|
||||||
|
Init,
|
||||||
|
#[structopt(name = "play", about = "Play next episode")]
|
||||||
|
Play,
|
||||||
|
#[structopt(name = "prev", about = "Decrease episode counter by one")]
|
||||||
|
Prev,
|
||||||
|
#[structopt(name = "next", about = "Increase episode counter by one")]
|
||||||
|
Next,
|
||||||
|
#[structopt(name = "update", about = "Update saved config")]
|
||||||
|
Update(UpdateOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(StructOpt, Debug)]
|
||||||
|
pub struct UpdateOptions {
|
||||||
|
#[structopt(
|
||||||
|
short,
|
||||||
|
long,
|
||||||
|
name = "episode",
|
||||||
|
about = "Update saved last episode"
|
||||||
|
)]
|
||||||
|
pub last_episode: Option<usize>,
|
||||||
|
#[structopt(
|
||||||
|
short,
|
||||||
|
long,
|
||||||
|
name = "command",
|
||||||
|
about = "Update saved command to show the next episode"
|
||||||
|
)]
|
||||||
|
pub command: Option<String>,
|
||||||
|
#[structopt(
|
||||||
|
short,
|
||||||
|
long,
|
||||||
|
name = "pattern",
|
||||||
|
about = "Update pattern for filenames"
|
||||||
|
)]
|
||||||
|
pub pattern: Option<String>,
|
||||||
|
}
|
103
src/config.rs
Normal file
103
src/config.rs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
use crate::result::{AppResult, AppError};
|
||||||
|
use crate::{CONFIG_PATH, UpdateOptions};
|
||||||
|
use std::io::{Write, Read};
|
||||||
|
|
||||||
|
#[derive(Serialize, Default, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
current_episode_count: usize,
|
||||||
|
pattern: String,
|
||||||
|
#[serde(default = "default_command")]
|
||||||
|
pub command: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_command() -> String {
|
||||||
|
String::from("mpv --fullscreen {}")
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn new(pattern: String, maybe_command: String) -> AppResult<Self> {
|
||||||
|
let mut command = maybe_command;
|
||||||
|
if pattern.is_empty() {
|
||||||
|
return Err(AppError::RuntimeError(
|
||||||
|
String::from("Pattern can't be empty")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if command.is_empty() {
|
||||||
|
command = default_command();
|
||||||
|
}
|
||||||
|
Ok(Self {
|
||||||
|
current_episode_count: 0,
|
||||||
|
pattern,
|
||||||
|
command,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(&self) -> AppResult<()> {
|
||||||
|
let json = serde_json::to_string_pretty(self)?;
|
||||||
|
let mut file = std::fs::File::create(CONFIG_PATH.as_str())?;
|
||||||
|
file.write_all(json.as_bytes())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read() -> AppResult<Self> {
|
||||||
|
let config_path = std::path::Path::new(CONFIG_PATH.as_str());
|
||||||
|
if !config_path.exists() {
|
||||||
|
return Err(
|
||||||
|
AppError::StdErr(String::from("Run 'awatch init' first."))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let mut file = std::fs::File::open(CONFIG_PATH.as_str())?;
|
||||||
|
let mut buffer = String::new();
|
||||||
|
file.read_to_string(&mut buffer)?;
|
||||||
|
let config: Self = serde_json::from_str(buffer.as_str())?;
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_current_episode(&self) -> AppResult<String> {
|
||||||
|
let current_dir = std::env::current_dir()?;
|
||||||
|
let mut names = Vec::new();
|
||||||
|
|
||||||
|
let episode_regex = regex::Regex::new(self.pattern.as_str())?;
|
||||||
|
for entry in std::fs::read_dir(current_dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let path = entry.path();
|
||||||
|
let meta = std::fs::metadata(&path)?;
|
||||||
|
if meta.is_dir() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let name = entry.file_name();
|
||||||
|
let name_str = name.into_string();
|
||||||
|
if let Ok(name) = name_str {
|
||||||
|
if episode_regex.is_match(name.as_str()) {
|
||||||
|
names.push(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alphanumeric_sort::sort_str_slice(names.as_mut_slice());
|
||||||
|
if let Some(episode) = names.get(self.current_episode_count) {
|
||||||
|
Ok(episode.clone())
|
||||||
|
} else {
|
||||||
|
Err(AppError::RuntimeError(String::from("This is the end.")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_episode(episode_func: fn(usize) -> AppResult<usize>) -> AppResult<()> {
|
||||||
|
let mut conf = Config::read()?;
|
||||||
|
conf.current_episode_count = episode_func(conf.current_episode_count)?;
|
||||||
|
conf.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_config(options: UpdateOptions) -> AppResult<()> {
|
||||||
|
let mut conf = Config::read()?;
|
||||||
|
if let Some(pattern) = options.pattern {
|
||||||
|
conf.pattern = pattern;
|
||||||
|
}
|
||||||
|
if let Some(command) = options.command {
|
||||||
|
conf.command = command;
|
||||||
|
}
|
||||||
|
if let Some(episode) = options.last_episode {
|
||||||
|
conf.current_episode_count = episode;
|
||||||
|
}
|
||||||
|
conf.save()
|
||||||
|
}
|
17
src/initialization.rs
Normal file
17
src/initialization.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use crate::result::AppResult;
|
||||||
|
use crate::config::Config;
|
||||||
|
|
||||||
|
pub fn init_config() -> AppResult<()> {
|
||||||
|
let stdin = std::io::stdin();
|
||||||
|
println!("How can we recognize anime files? Enter filename regex.");
|
||||||
|
let mut pattern = String::new();
|
||||||
|
stdin.read_line(&mut pattern)?;
|
||||||
|
pattern = pattern.trim().to_string();
|
||||||
|
println!("How can we show you the next episode? If 'mpv --fullscreen {{}}' is correct, leave it blank.");
|
||||||
|
let mut command = String::new();
|
||||||
|
stdin.read_line(&mut command)?;
|
||||||
|
command = command.trim().to_string();
|
||||||
|
let config = Config::new(pattern, command)?;
|
||||||
|
config.save()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
30
src/main.rs
Normal file
30
src/main.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate failure;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate failure_derive;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref CONFIG_PATH: String = String::from(".awatch.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
use structopt::StructOpt;
|
||||||
|
|
||||||
|
use crate::run_modes::run;
|
||||||
|
use crate::result::AppResult;
|
||||||
|
|
||||||
|
pub mod result;
|
||||||
|
pub mod config;
|
||||||
|
pub mod run_modes;
|
||||||
|
pub mod initialization;
|
||||||
|
|
||||||
|
include!("cli.rs");
|
||||||
|
|
||||||
|
fn main() -> AppResult<()> {
|
||||||
|
let opt: Opt = Opt::from_args();
|
||||||
|
run(opt)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
29
src/result.rs
Normal file
29
src/result.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
pub type AppResult<T> = Result<T, AppError>;
|
||||||
|
|
||||||
|
#[derive(Debug, Fail)]
|
||||||
|
pub enum AppError {
|
||||||
|
#[fail(display = "Execution failed: {}", _0)]
|
||||||
|
StdErr(String),
|
||||||
|
#[fail(display = "Config processing failed: {}", _0)]
|
||||||
|
ParseError(String),
|
||||||
|
#[fail(display = "Error was found: {}", _0)]
|
||||||
|
RuntimeError(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for AppError {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
Self::StdErr(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<serde_json::error::Error> for AppError {
|
||||||
|
fn from(err: serde_json::error::Error) -> Self {
|
||||||
|
Self::StdErr(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<regex::Error> for AppError {
|
||||||
|
fn from(err: regex::Error) -> Self {
|
||||||
|
Self::RuntimeError(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
61
src/run_modes.rs
Normal file
61
src/run_modes.rs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
use crate::{Opt, RunMode};
|
||||||
|
use crate::result::{AppResult, AppError};
|
||||||
|
use crate::initialization::init_config;
|
||||||
|
use crate::config::{update_episode, update_config, Config};
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
pub fn run(opts: Opt) -> AppResult<()> {
|
||||||
|
let mode = opts.mode.unwrap_or_else(|| RunMode::Play);
|
||||||
|
match mode {
|
||||||
|
RunMode::Init => {
|
||||||
|
init_config()
|
||||||
|
}
|
||||||
|
RunMode::Play => {
|
||||||
|
play()
|
||||||
|
}
|
||||||
|
RunMode::Prev => {
|
||||||
|
update_episode(prev_episode)
|
||||||
|
}
|
||||||
|
RunMode::Next => {
|
||||||
|
update_episode(next_episode)
|
||||||
|
}
|
||||||
|
RunMode::Update(options) => {
|
||||||
|
update_config(options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_episode(current: usize) -> AppResult<usize> {
|
||||||
|
if let Some(episode) = current.checked_sub(1) {
|
||||||
|
Ok(episode)
|
||||||
|
} else {
|
||||||
|
Err(AppError::RuntimeError(
|
||||||
|
String::from("Episode can't be less than zero.")
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_episode(current: usize) -> AppResult<usize> {
|
||||||
|
if let Some(episode) = current.checked_add(1) {
|
||||||
|
Ok(episode)
|
||||||
|
} else {
|
||||||
|
Err(AppError::RuntimeError(
|
||||||
|
String::from("Reached usize limit. Sorry.")
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn play() -> AppResult<()> {
|
||||||
|
let conf = Config::read()?;
|
||||||
|
let mut episode = conf.get_current_episode()?;
|
||||||
|
while !episode.is_empty() {
|
||||||
|
let mut child = Command::new("sh")
|
||||||
|
.arg("-c")
|
||||||
|
.arg(conf.command.replace("{}", episode.as_str()))
|
||||||
|
.spawn()?;
|
||||||
|
child.wait()?;
|
||||||
|
update_episode(next_episode)?;
|
||||||
|
episode = conf.get_current_episode()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
Reference in New Issue
Block a user