mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-11-28 13:09:10 -05:00
upgrade bpaf to nearly-0.9.1
* take advantage of new features to default to `--help` and to print the defaults * remove blank lines from argument help docstrings to avoid truncating the output on single `--help` arg (as opposed to `--help --help`) I'd use the actual released 0.9.1 but it looks like it's not quite out yet. Will switch over when it is.
This commit is contained in:
@@ -11,7 +11,7 @@ use std::path::PathBuf;
|
||||
|
||||
/// Checks database integrity (like fsck).
|
||||
#[derive(Bpaf, Debug)]
|
||||
#[bpaf(options)]
|
||||
#[bpaf(command("check"))]
|
||||
pub struct Args {
|
||||
#[bpaf(external(crate::parse_db_dir))]
|
||||
db_dir: PathBuf,
|
||||
@@ -20,29 +20,22 @@ pub struct Args {
|
||||
compare_lens: bool,
|
||||
|
||||
/// Trashes sample files without matching recording rows in the database.
|
||||
/// This addresses `Missing ... row` errors.
|
||||
///
|
||||
/// The ids are added to the `garbage` table to indicate the files need to
|
||||
/// be deleted. Garbage is collected on normal startup.
|
||||
/// This addresses `Missing ... row` errors. The ids are added to the
|
||||
/// `garbage` table to indicate the files need to be deleted. Garbage is
|
||||
/// collected on normal startup.
|
||||
trash_orphan_sample_files: bool,
|
||||
|
||||
/// Deletes recording rows in the database without matching sample files.
|
||||
///
|
||||
/// This addresses `Recording ... missing file` errors.
|
||||
delete_orphan_rows: bool,
|
||||
|
||||
/// Trashes recordings when their database rows appear corrupt.
|
||||
/// This addresses "bad video_index" errors.
|
||||
///
|
||||
/// The ids are added to the `garbage` table to indicate their files need to
|
||||
/// be deleted. Garbage is collected on normal startup.
|
||||
/// This addresses "bad video_index" errors. The ids are added to the
|
||||
/// `garbage` table to indicate their files need to be deleted. Garbage is
|
||||
/// collected on normal startup.
|
||||
trash_corrupt_rows: bool,
|
||||
}
|
||||
|
||||
pub fn subcommand() -> impl bpaf::Parser<Args> {
|
||||
crate::subcommand(args(), "check")
|
||||
}
|
||||
|
||||
pub fn run(args: Args) -> Result<i32, Error> {
|
||||
let (_db_dir, mut conn) = super::open_conn(&args.db_dir, super::OpenMode::ReadWrite)?;
|
||||
check::run(
|
||||
|
||||
@@ -21,16 +21,12 @@ mod users;
|
||||
|
||||
/// Interactively edits configuration.
|
||||
#[derive(Bpaf, Debug)]
|
||||
#[bpaf(options)]
|
||||
#[bpaf(command("config"))]
|
||||
pub struct Args {
|
||||
#[bpaf(external(crate::parse_db_dir))]
|
||||
db_dir: PathBuf,
|
||||
}
|
||||
|
||||
pub fn subcommand() -> impl bpaf::Parser<Args> {
|
||||
crate::subcommand(args(), "config")
|
||||
}
|
||||
|
||||
pub fn run(args: Args) -> Result<i32, Error> {
|
||||
let (_db_dir, conn) = super::open_conn(&args.db_dir, super::OpenMode::ReadWrite)?;
|
||||
let clocks = clock::RealClocks {};
|
||||
|
||||
@@ -9,16 +9,12 @@ use std::path::PathBuf;
|
||||
|
||||
/// Initializes a database.
|
||||
#[derive(Bpaf, Debug)]
|
||||
#[bpaf(options)]
|
||||
#[bpaf(command("init"))]
|
||||
pub struct Args {
|
||||
#[bpaf(external(crate::parse_db_dir))]
|
||||
db_dir: PathBuf,
|
||||
}
|
||||
|
||||
pub fn subcommand() -> impl bpaf::Parser<Args> {
|
||||
crate::subcommand(args(), "init")
|
||||
}
|
||||
|
||||
pub fn run(args: Args) -> Result<i32, Error> {
|
||||
let (_db_dir, mut conn) = super::open_conn(&args.db_dir, super::OpenMode::Create)?;
|
||||
|
||||
|
||||
@@ -25,19 +25,16 @@ fn parse_flags(flags: String) -> Result<Vec<SessionFlag>, Error> {
|
||||
}
|
||||
|
||||
/// Logs in a user, returning the session cookie.
|
||||
///
|
||||
///
|
||||
/// This is a privileged command that directly accesses the database. It doesn't check the
|
||||
/// user's password and even can be used to create sessions with permissions the user doesn't
|
||||
/// have.
|
||||
#[derive(Bpaf, Debug, PartialEq, Eq)]
|
||||
#[bpaf(options)]
|
||||
#[bpaf(command("login"))]
|
||||
pub struct Args {
|
||||
#[bpaf(external(crate::parse_db_dir))]
|
||||
db_dir: PathBuf,
|
||||
|
||||
/// Creates a session with the given permissions, as a JSON object.
|
||||
///
|
||||
/// E.g. `{"viewVideo": true}`. See `ref/api.md` for a description of `Permissions`.
|
||||
/// If unspecified, uses user's default permissions.
|
||||
#[bpaf(argument::<String>("PERMS"), parse(parse_perms), optional)]
|
||||
@@ -47,19 +44,18 @@ pub struct Args {
|
||||
#[bpaf(argument("DOMAIN"))]
|
||||
domain: Option<String>,
|
||||
|
||||
/// Writes the cookie to a new curl-compatible cookie-jar file.
|
||||
///
|
||||
/// `--domain` must be specified. This file can be used later with curl's `--cookie` flag.
|
||||
/// Writes the cookie to a new curl-compatible cookie-jar file. `--domain`
|
||||
/// must be specified. This file can be used later with curl's `--cookie`
|
||||
/// flag.
|
||||
#[bpaf(argument("PATH"))]
|
||||
curl_cookie_jar: Option<PathBuf>,
|
||||
|
||||
/// Sets the given db::auth::SessionFlags.
|
||||
///
|
||||
/// default: `http-only,secure,same-site,same-site-strict`.
|
||||
#[bpaf(
|
||||
argument::<String>("FLAGS"),
|
||||
fallback_with(|| Ok::<_, std::convert::Infallible>("http-only,secure,same-site,same-site-strict".to_owned())),
|
||||
parse(parse_flags),
|
||||
fallback("http-only,secure,same-site,same-site-strict".to_string()),
|
||||
debug_fallback,
|
||||
parse(parse_flags)
|
||||
)]
|
||||
session_flags: Vec<SessionFlag>,
|
||||
|
||||
@@ -68,10 +64,6 @@ pub struct Args {
|
||||
username: String,
|
||||
}
|
||||
|
||||
pub fn subcommand() -> impl bpaf::Parser<Args> {
|
||||
crate::subcommand(args(), "login")
|
||||
}
|
||||
|
||||
pub fn run(args: Args) -> Result<i32, Error> {
|
||||
let clocks = clock::RealClocks {};
|
||||
let (_db_dir, conn) = super::open_conn(&args.db_dir, super::OpenMode::ReadWrite)?;
|
||||
@@ -155,11 +147,14 @@ fn curl_cookie(cookie: &str, flags: i32, domain: &str) -> String {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use bpaf::Parser;
|
||||
|
||||
#[test]
|
||||
fn parse_args() {
|
||||
let args = args()
|
||||
.to_options()
|
||||
.run_inner(bpaf::Args::from(&[
|
||||
"login",
|
||||
"--permissions",
|
||||
"{\"viewVideo\": true}",
|
||||
"--session-flags",
|
||||
|
||||
@@ -14,7 +14,6 @@ use crate::json::Permissions;
|
||||
fn default_db_dir() -> PathBuf {
|
||||
crate::DEFAULT_DB_DIR.into()
|
||||
}
|
||||
|
||||
fn default_ui_dir() -> PathBuf {
|
||||
"/usr/local/lib/moonfire-nvr/ui".into()
|
||||
}
|
||||
@@ -28,7 +27,6 @@ pub struct ConfigFile {
|
||||
|
||||
/// Directory holding the SQLite3 index database.
|
||||
///
|
||||
///
|
||||
/// default: `/var/lib/moonfire-nvr/db`.
|
||||
#[serde(default = "default_db_dir")]
|
||||
pub db_dir: PathBuf,
|
||||
|
||||
@@ -27,25 +27,18 @@ mod config;
|
||||
|
||||
/// Runs the server, saving recordings and allowing web access.
|
||||
#[derive(Bpaf, Debug)]
|
||||
#[bpaf(options)]
|
||||
#[bpaf(command("run"))]
|
||||
pub struct Args {
|
||||
/// Path to configuration file.
|
||||
///
|
||||
/// default: `/etc/moonfire-nvr.toml`. See `ref/config.md` for config file documentation.
|
||||
#[bpaf(short, long, argument("PATH"), fallback_with(|| Ok::<_, Error>("/etc/moonfire-nvr.toml".into())))]
|
||||
/// Path to configuration file. See `ref/config.md` for config file documentation.
|
||||
#[bpaf(short, long, argument("PATH"), fallback("/etc/moonfire-nvr.toml".into()), debug_fallback)]
|
||||
config: PathBuf,
|
||||
|
||||
/// Opens the database in read-only mode and disables recording.
|
||||
///
|
||||
/// Note this is incompatible with session authentication; consider adding
|
||||
/// a bind with `allowUnauthenticatedPermissions` to your config.
|
||||
read_only: bool,
|
||||
}
|
||||
|
||||
pub fn subcommand() -> impl bpaf::Parser<Args> {
|
||||
crate::subcommand(args(), "run")
|
||||
}
|
||||
|
||||
// These are used in a hack to get the name of the current time zone (e.g. America/Los_Angeles).
|
||||
// They seem to be correct for Linux and macOS at least.
|
||||
const LOCALTIME_PATH: &str = "/etc/localtime";
|
||||
|
||||
@@ -18,28 +18,22 @@ use std::process::Command;
|
||||
/// Note this locks the database to prevent simultaneous access with a running server. The
|
||||
/// server maintains cached state which could be invalidated otherwise.
|
||||
#[derive(Bpaf, Debug, PartialEq, Eq)]
|
||||
#[bpaf(options)]
|
||||
#[bpaf(command("sql"))]
|
||||
pub struct Args {
|
||||
#[bpaf(external(crate::parse_db_dir))]
|
||||
db_dir: PathBuf,
|
||||
|
||||
/// Opens the database in read-only mode and locks it only for shared access.
|
||||
///
|
||||
/// This can be run simultaneously with `moonfire-nvr run --read-only`.
|
||||
read_only: bool,
|
||||
|
||||
/// Arguments to pass to sqlite3.
|
||||
///
|
||||
/// Use the `--` separator to pass sqlite3 options, as in
|
||||
/// `moonfire-nvr sql -- -line 'select username from user'`.
|
||||
#[bpaf(positional)]
|
||||
arg: Vec<OsString>,
|
||||
}
|
||||
|
||||
pub fn subcommand() -> impl bpaf::Parser<Args> {
|
||||
crate::subcommand(args(), "sql")
|
||||
}
|
||||
|
||||
pub fn run(args: Args) -> Result<i32, Error> {
|
||||
let mode = if args.read_only {
|
||||
OpenMode::ReadOnly
|
||||
@@ -65,11 +59,14 @@ pub fn run(args: Args) -> Result<i32, Error> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use bpaf::Parser;
|
||||
|
||||
#[test]
|
||||
fn parse_args() {
|
||||
let args = args()
|
||||
.to_options()
|
||||
.run_inner(bpaf::Args::from(&[
|
||||
"sql",
|
||||
"--db-dir",
|
||||
"/foo/bar",
|
||||
"--",
|
||||
|
||||
@@ -7,7 +7,7 @@ use failure::Error;
|
||||
|
||||
/// Translates between integer and human-readable timestamps.
|
||||
#[derive(Bpaf, Debug)]
|
||||
#[bpaf(options)]
|
||||
#[bpaf(command("config"))]
|
||||
pub struct Args {
|
||||
/// Timestamp(s) to translate.
|
||||
///
|
||||
@@ -19,10 +19,6 @@ pub struct Args {
|
||||
timestamps: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn subcommand() -> impl bpaf::Parser<Args> {
|
||||
crate::subcommand(args(), "ts")
|
||||
}
|
||||
|
||||
pub fn run(args: Args) -> Result<i32, Error> {
|
||||
for timestamp in &args.timestamps {
|
||||
let t = db::recording::Time::parse(timestamp)?;
|
||||
|
||||
@@ -10,7 +10,7 @@ use failure::Error;
|
||||
|
||||
/// Upgrades to the latest database schema.
|
||||
#[derive(Bpaf, Debug)]
|
||||
#[bpaf(options)]
|
||||
#[bpaf(command("upgrade"))]
|
||||
pub struct Args {
|
||||
#[bpaf(external(crate::parse_db_dir))]
|
||||
db_dir: std::path::PathBuf,
|
||||
@@ -20,23 +20,16 @@ pub struct Args {
|
||||
sample_file_dir: Option<std::path::PathBuf>,
|
||||
|
||||
/// Resets the SQLite journal_mode to the specified mode prior to
|
||||
/// the upgrade.
|
||||
///
|
||||
///
|
||||
/// default: `delete` (recommended). `off` is very dangerous but may be
|
||||
/// desirable in some circumstances. See `guide/schema.md` for more
|
||||
/// information. The journal mode will be reset to `wal` after the upgrade.
|
||||
#[bpaf(argument("MODE"), fallback_with(|| Ok::<_, std::convert::Infallible>("delete".into())))]
|
||||
/// the upgrade. `off` is very dangerous but may be desirable in some
|
||||
/// circumstances. See `guide/schema.md` for more information. The journal
|
||||
/// mode will be reset to `wal` after the upgrade.
|
||||
#[bpaf(argument("MODE"), fallback("delete".to_owned()), debug_fallback)]
|
||||
preset_journal: String,
|
||||
|
||||
/// Skips the normal post-upgrade vacuum operation.
|
||||
no_vacuum: bool,
|
||||
}
|
||||
|
||||
pub fn subcommand() -> impl bpaf::Parser<Args> {
|
||||
crate::subcommand(args(), "upgrade")
|
||||
}
|
||||
|
||||
pub fn run(args: Args) -> Result<i32, Error> {
|
||||
let (_db_dir, mut conn) = super::open_conn(&args.db_dir, super::OpenMode::ReadWrite)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user