Compare commits
4 commits
aa1fbbc4b8
...
3745b88730
| Author | SHA1 | Date | |
|---|---|---|---|
| 3745b88730 | |||
| a5d143758a | |||
| 693ffbc764 | |||
| ee96033639 |
11 changed files with 149 additions and 149 deletions
|
|
@ -49,12 +49,17 @@ jobs:
|
||||||
if: steps.version.outputs.SKIP != 'true'
|
if: steps.version.outputs.SKIP != 'true'
|
||||||
run: nix build .#streamd-musl -o result-musl
|
run: nix build .#streamd-musl -o result-musl
|
||||||
|
|
||||||
|
- name: Build Windows binary
|
||||||
|
if: steps.version.outputs.SKIP != 'true'
|
||||||
|
run: nix build .#streamd-windows -o result-windows
|
||||||
|
|
||||||
- name: Prepare release artifacts
|
- name: Prepare release artifacts
|
||||||
if: steps.version.outputs.SKIP != 'true'
|
if: steps.version.outputs.SKIP != 'true'
|
||||||
run: |
|
run: |
|
||||||
mkdir -p release
|
mkdir -p release
|
||||||
cp result-deb release/streamd_${{ steps.version.outputs.VERSION }}_amd64.deb
|
cp result-deb release/streamd_${{ steps.version.outputs.VERSION }}_amd64.deb
|
||||||
cp result-musl/bin/streamd release/streamd-${{ steps.version.outputs.VERSION }}-linux-x86_64
|
cp result-musl/bin/streamd release/streamd-${{ steps.version.outputs.VERSION }}-linux-x86_64
|
||||||
|
cp result-windows/bin/streamd.exe release/streamd-${{ steps.version.outputs.VERSION }}-windows-x86_64.exe
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
if: steps.version.outputs.SKIP != 'true'
|
if: steps.version.outputs.SKIP != 'true'
|
||||||
|
|
|
||||||
38
Cargo.lock
generated
38
Cargo.lock
generated
|
|
@ -135,9 +135,9 @@ checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.59"
|
version = "1.2.60"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283"
|
checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"shlex",
|
"shlex",
|
||||||
|
|
@ -197,9 +197,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_complete"
|
name = "clap_complete"
|
||||||
version = "4.6.1"
|
version = "4.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "406e68b4de5c59cfb8f750a7cbd4d31ae153788b8352167c1e5f4fc26e8c91e9"
|
checksum = "3ff7a1dccbdd8b078c2bdebff47e404615151534d5043da397ec50286816f9cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
]
|
]
|
||||||
|
|
@ -432,9 +432,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.94"
|
version = "0.3.95"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9"
|
checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
|
@ -448,15 +448,15 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.184"
|
version = "0.2.185"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
|
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
version = "0.1.15"
|
version = "0.1.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08"
|
checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
@ -787,7 +787,7 @@ checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "streamd"
|
name = "streamd"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
|
|
@ -1016,9 +1016,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.117"
|
version = "0.2.118"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0"
|
checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
|
@ -1029,9 +1029,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.117"
|
version = "0.2.118"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be"
|
checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
|
|
@ -1039,9 +1039,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.117"
|
version = "0.2.118"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2"
|
checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -1052,9 +1052,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.117"
|
version = "0.2.118"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b"
|
checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "streamd"
|
name = "streamd"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Personal knowledge management and time-tracking CLI using @Tag annotations"
|
description = "Personal knowledge management and time-tracking CLI using @Tag annotations"
|
||||||
license = "AGPL-3.0-only"
|
license = "AGPL-3.0-only"
|
||||||
|
|
|
||||||
35
flake.nix
35
flake.nix
|
|
@ -132,6 +132,38 @@
|
||||||
in
|
in
|
||||||
craneLib.buildPackage (commonArgs // { inherit cargoArtifacts; });
|
craneLib.buildPackage (commonArgs // { inherit cargoArtifacts; });
|
||||||
|
|
||||||
|
mkWindowsCraneLib =
|
||||||
|
system:
|
||||||
|
let
|
||||||
|
pkgs = mkPkgs system;
|
||||||
|
toolchain = pkgs.rust-bin.stable.latest.default.override {
|
||||||
|
targets = [ "x86_64-pc-windows-gnu" ];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
(crane.mkLib pkgs).overrideToolchain toolchain;
|
||||||
|
|
||||||
|
mkStreamdWindows =
|
||||||
|
system:
|
||||||
|
let
|
||||||
|
pkgs = mkPkgs system;
|
||||||
|
pkgsCross = pkgs.pkgsCross.mingwW64;
|
||||||
|
craneLib = mkWindowsCraneLib system;
|
||||||
|
commonArgs = {
|
||||||
|
src = craneLib.path ./.;
|
||||||
|
pname = "streamd";
|
||||||
|
inherit version;
|
||||||
|
strictDeps = true;
|
||||||
|
CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu";
|
||||||
|
CC_x86_64_pc_windows_gnu = "${pkgsCross.stdenv.cc}/bin/x86_64-w64-mingw32-gcc";
|
||||||
|
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = "${pkgsCross.stdenv.cc}/bin/x86_64-w64-mingw32-gcc";
|
||||||
|
nativeBuildInputs = [ pkgsCross.stdenv.cc ];
|
||||||
|
buildInputs = [ pkgsCross.windows.pthreads ];
|
||||||
|
doCheck = false;
|
||||||
|
};
|
||||||
|
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
|
||||||
|
in
|
||||||
|
craneLib.buildPackage (commonArgs // { inherit cargoArtifacts; });
|
||||||
|
|
||||||
mkStreamdDeb =
|
mkStreamdDeb =
|
||||||
system:
|
system:
|
||||||
let
|
let
|
||||||
|
|
@ -181,9 +213,10 @@
|
||||||
streamd = mkStreamd system;
|
streamd = mkStreamd system;
|
||||||
streamd-musl = mkStreamdMusl system;
|
streamd-musl = mkStreamdMusl system;
|
||||||
streamd-deb = mkStreamdDeb system;
|
streamd-deb = mkStreamdDeb system;
|
||||||
|
streamd-windows = mkStreamdWindows system;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit streamd streamd-musl streamd-deb;
|
inherit streamd streamd-musl streamd-deb streamd-windows;
|
||||||
default = streamd;
|
default = streamd;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,38 +4,13 @@ use std::process::Command;
|
||||||
|
|
||||||
use chrono::{Days, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
|
use chrono::{Days, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
use walkdir::WalkDir;
|
|
||||||
|
|
||||||
use crate::config::Settings;
|
use crate::config::Settings;
|
||||||
use crate::error::StreamdError;
|
use crate::error::StreamdError;
|
||||||
use crate::extract::parse_markdown_file;
|
use crate::models::RepositoryConfiguration;
|
||||||
use crate::localize::localize_stream_file;
|
|
||||||
use crate::models::{LocalizedShard, RepositoryConfiguration};
|
|
||||||
use crate::timesheet::load_repository_config;
|
use crate::timesheet::load_repository_config;
|
||||||
|
|
||||||
fn load_all_shards(base_folder: &Path, tz: Tz) -> Result<Vec<LocalizedShard>, StreamdError> {
|
use super::load_markdown_shards;
|
||||||
let config = RepositoryConfiguration::new();
|
|
||||||
let mut shards = Vec::new();
|
|
||||||
|
|
||||||
for entry in WalkDir::new(base_folder)
|
|
||||||
.max_depth(1)
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.ok())
|
|
||||||
{
|
|
||||||
let path = entry.path();
|
|
||||||
if path.extension().map(|e| e == "md").unwrap_or(false) {
|
|
||||||
let file_name = path.to_string_lossy().to_string();
|
|
||||||
let content = fs::read_to_string(path)?;
|
|
||||||
let stream_file = parse_markdown_file(&file_name, &content);
|
|
||||||
|
|
||||||
if let Ok(shard) = localize_stream_file(&stream_file, &config, tz) {
|
|
||||||
shards.push(shard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(shards)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(date: Option<String>) -> Result<(), StreamdError> {
|
pub fn run(date: Option<String>) -> Result<(), StreamdError> {
|
||||||
let settings = Settings::load()?;
|
let settings = Settings::load()?;
|
||||||
|
|
@ -69,7 +44,7 @@ pub fn run(date: Option<String>) -> Result<(), StreamdError> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_timezone(&Utc);
|
.with_timezone(&Utc);
|
||||||
|
|
||||||
let all_shards = load_all_shards(base_folder, tz)?;
|
let all_shards = load_markdown_shards(base_folder, &RepositoryConfiguration::new(), tz)?;
|
||||||
let mut daily_shards: Vec<_> = all_shards
|
let mut daily_shards: Vec<_> = all_shards
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|s| {
|
.filter(|s| {
|
||||||
|
|
@ -77,8 +52,9 @@ pub fn run(date: Option<String>) -> Result<(), StreamdError> {
|
||||||
.get("file_type")
|
.get("file_type")
|
||||||
.map(|v| v == "daily")
|
.map(|v| v == "daily")
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
|
&& s.moment >= day_start
|
||||||
|
&& s.moment < day_end
|
||||||
})
|
})
|
||||||
.filter(|s| s.moment >= day_start && s.moment < day_end)
|
|
||||||
.collect();
|
.collect();
|
||||||
daily_shards.sort_by_key(|s| s.moment);
|
daily_shards.sort_by_key(|s| s.moment);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,19 @@
|
||||||
use std::fs;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use walkdir::WalkDir;
|
|
||||||
|
|
||||||
use crate::config::Settings;
|
use crate::config::Settings;
|
||||||
use crate::error::StreamdError;
|
use crate::error::StreamdError;
|
||||||
use crate::extract::parse_markdown_file;
|
use crate::localize::TaskConfiguration;
|
||||||
use crate::localize::{localize_stream_file, TaskConfiguration};
|
|
||||||
use crate::models::LocalizedShard;
|
|
||||||
|
|
||||||
fn all_files() -> Result<Vec<LocalizedShard>, StreamdError> {
|
use super::load_markdown_shards;
|
||||||
let settings = Settings::load()?;
|
|
||||||
let mut shards = Vec::new();
|
|
||||||
|
|
||||||
for entry in WalkDir::new(&settings.base_folder)
|
|
||||||
.max_depth(1)
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.ok())
|
|
||||||
{
|
|
||||||
let path = entry.path();
|
|
||||||
if path.extension().map(|e| e == "md").unwrap_or(false) {
|
|
||||||
let file_name = path.to_string_lossy().to_string();
|
|
||||||
let content = fs::read_to_string(path)?;
|
|
||||||
let stream_file = parse_markdown_file(&file_name, &content);
|
|
||||||
|
|
||||||
if let Ok(shard) =
|
|
||||||
localize_stream_file(&stream_file, &TaskConfiguration, chrono_tz::UTC)
|
|
||||||
{
|
|
||||||
shards.push(shard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(shards)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(number: i32) -> Result<(), StreamdError> {
|
pub fn run(number: i32) -> Result<(), StreamdError> {
|
||||||
let all_shards = all_files()?;
|
let settings = Settings::load()?;
|
||||||
|
let all_shards = load_markdown_shards(
|
||||||
|
Path::new(&settings.base_folder),
|
||||||
|
&TaskConfiguration,
|
||||||
|
chrono_tz::UTC,
|
||||||
|
)?;
|
||||||
|
|
||||||
// Sort by moment (timestamp)
|
// Sort by moment (timestamp)
|
||||||
let mut sorted_shards = all_shards;
|
let mut sorted_shards = all_shards;
|
||||||
|
|
@ -67,7 +44,13 @@ pub fn run(number: i32) -> Result<(), StreamdError> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(file_path) = sorted_shards[selected_index].location.get("file") {
|
if let Some(file_path) = sorted_shards[selected_index].location.get("file") {
|
||||||
let editor = std::env::var("EDITOR").unwrap_or_else(|_| "vi".to_string());
|
let editor = std::env::var("EDITOR").unwrap_or_else(|_| {
|
||||||
|
if cfg!(windows) {
|
||||||
|
"notepad".to_string()
|
||||||
|
} else {
|
||||||
|
"vi".to_string()
|
||||||
|
}
|
||||||
|
});
|
||||||
Command::new(&editor).arg(file_path).status()?;
|
Command::new(&editor).arg(file_path).status()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,41 @@
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use chrono_tz::Tz;
|
||||||
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
use crate::error::StreamdError;
|
||||||
|
use crate::extract::parse_markdown_file;
|
||||||
|
use crate::localize::localize_stream_file;
|
||||||
|
use crate::models::{LocalizedShard, RepositoryConfiguration};
|
||||||
|
|
||||||
pub mod completions;
|
pub mod completions;
|
||||||
pub mod daily;
|
pub mod daily;
|
||||||
pub mod edit;
|
pub mod edit;
|
||||||
pub mod new;
|
pub mod new;
|
||||||
pub mod timesheet;
|
pub mod timesheet;
|
||||||
pub mod todo;
|
pub mod todo;
|
||||||
|
|
||||||
|
pub fn load_markdown_shards(
|
||||||
|
base_folder: &Path,
|
||||||
|
config: &RepositoryConfiguration,
|
||||||
|
tz: Tz,
|
||||||
|
) -> Result<Vec<LocalizedShard>, StreamdError> {
|
||||||
|
let mut shards = Vec::new();
|
||||||
|
for entry in WalkDir::new(base_folder)
|
||||||
|
.max_depth(1)
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|e| e.ok())
|
||||||
|
{
|
||||||
|
let path = entry.path();
|
||||||
|
if path.extension().map(|e| e == "md").unwrap_or(false) {
|
||||||
|
let file_name = path.to_string_lossy().to_string();
|
||||||
|
let content = fs::read_to_string(path)?;
|
||||||
|
let stream_file = parse_markdown_file(&file_name, &content);
|
||||||
|
if let Ok(shard) = localize_stream_file(&stream_file, config, tz) {
|
||||||
|
shards.push(shard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(shards)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,13 @@ pub fn run() -> Result<(), StreamdError> {
|
||||||
drop(file);
|
drop(file);
|
||||||
|
|
||||||
// Open in editor
|
// Open in editor
|
||||||
let editor = std::env::var("EDITOR").unwrap_or_else(|_| "vi".to_string());
|
let editor = std::env::var("EDITOR").unwrap_or_else(|_| {
|
||||||
|
if cfg!(windows) {
|
||||||
|
"notepad".to_string()
|
||||||
|
} else {
|
||||||
|
"vi".to_string()
|
||||||
|
}
|
||||||
|
});
|
||||||
let status = Command::new(&editor).arg(&preliminary_path).status()?;
|
let status = Command::new(&editor).arg(&preliminary_path).status()?;
|
||||||
|
|
||||||
if !status.success() {
|
if !status.success() {
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,23 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use chrono::Datelike;
|
use chrono::Datelike;
|
||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
use walkdir::WalkDir;
|
|
||||||
|
|
||||||
use crate::config::Settings;
|
use crate::config::Settings;
|
||||||
|
|
||||||
const SEPARATOR_WIDTH: usize = 71;
|
const SEPARATOR_WIDTH: usize = 71;
|
||||||
const COLUMN_SEPARATOR_WIDTH: usize = 65;
|
const COLUMN_SEPARATOR_WIDTH: usize = 65;
|
||||||
use crate::error::StreamdError;
|
use crate::error::StreamdError;
|
||||||
use crate::extract::parse_markdown_file;
|
use crate::models::Timesheet;
|
||||||
use crate::localize::localize_stream_file;
|
|
||||||
use crate::models::{LocalizedShard, Timesheet};
|
|
||||||
use crate::timesheet::{
|
use crate::timesheet::{
|
||||||
extract_timesheets, generate_report, load_repository_config, BasicTimesheetConfiguration,
|
extract_timesheets, generate_report, load_repository_config, BasicTimesheetConfiguration,
|
||||||
DayType, DayWarning, MonthReport, TimesheetReport,
|
DayType, DayWarning, MonthReport, TimesheetReport,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn load_all_shards(base_folder: &Path, tz: Tz) -> Result<Vec<LocalizedShard>, StreamdError> {
|
use super::load_markdown_shards;
|
||||||
let mut shards = Vec::new();
|
|
||||||
|
|
||||||
for entry in WalkDir::new(base_folder)
|
|
||||||
.max_depth(1)
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.ok())
|
|
||||||
{
|
|
||||||
let path = entry.path();
|
|
||||||
if path.extension().map(|e| e == "md").unwrap_or(false) {
|
|
||||||
let file_name = path.to_string_lossy().to_string();
|
|
||||||
let content = fs::read_to_string(path)?;
|
|
||||||
let stream_file = parse_markdown_file(&file_name, &content);
|
|
||||||
|
|
||||||
if let Ok(shard) = localize_stream_file(&stream_file, &BasicTimesheetConfiguration, tz)
|
|
||||||
{
|
|
||||||
shards.push(shard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(shards)
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DisplayMode {
|
enum DisplayMode {
|
||||||
Minutes,
|
Minutes,
|
||||||
|
|
@ -350,7 +324,7 @@ pub fn run(decimal: bool, debug: bool) -> Result<(), StreamdError> {
|
||||||
let now = Utc::now();
|
let now = Utc::now();
|
||||||
|
|
||||||
// Load all markdown files and extract timesheets
|
// Load all markdown files and extract timesheets
|
||||||
let all_shards = load_all_shards(base_folder, tz)?;
|
let all_shards = load_markdown_shards(base_folder, &BasicTimesheetConfiguration, tz)?;
|
||||||
let timesheets = extract_timesheets(&all_shards, now, tz)?;
|
let timesheets = extract_timesheets(&all_shards, now, tz)?;
|
||||||
|
|
||||||
// Generate the report
|
// Generate the report
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,24 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use walkdir::WalkDir;
|
|
||||||
|
|
||||||
use crate::config::Settings;
|
use crate::config::Settings;
|
||||||
use crate::error::StreamdError;
|
use crate::error::StreamdError;
|
||||||
use crate::extract::parse_markdown_file;
|
use crate::localize::TaskConfiguration;
|
||||||
use crate::localize::{localize_stream_file, TaskConfiguration};
|
|
||||||
use crate::models::LocalizedShard;
|
use crate::models::LocalizedShard;
|
||||||
use crate::query::find_shard_by_position;
|
use crate::query::find_shard_by_position;
|
||||||
|
|
||||||
fn all_files() -> Result<Vec<LocalizedShard>, StreamdError> {
|
use super::load_markdown_shards;
|
||||||
let settings = Settings::load()?;
|
|
||||||
let mut shards = Vec::new();
|
|
||||||
|
|
||||||
for entry in WalkDir::new(&settings.base_folder)
|
|
||||||
.max_depth(1)
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.ok())
|
|
||||||
{
|
|
||||||
let path = entry.path();
|
|
||||||
if path.extension().map(|e| e == "md").unwrap_or(false) {
|
|
||||||
let file_name = path.to_string_lossy().to_string();
|
|
||||||
let content = fs::read_to_string(path)?;
|
|
||||||
let stream_file = parse_markdown_file(&file_name, &content);
|
|
||||||
|
|
||||||
if let Ok(shard) =
|
|
||||||
localize_stream_file(&stream_file, &TaskConfiguration, chrono_tz::UTC)
|
|
||||||
{
|
|
||||||
shards.push(shard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(shards)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn collect_open_tasks(show_future: bool) -> Result<Vec<LocalizedShard>, StreamdError> {
|
pub fn collect_open_tasks(show_future: bool) -> Result<Vec<LocalizedShard>, StreamdError> {
|
||||||
let all_shards = all_files()?;
|
let settings = Settings::load()?;
|
||||||
|
let all_shards = load_markdown_shards(
|
||||||
|
Path::new(&settings.base_folder),
|
||||||
|
&TaskConfiguration,
|
||||||
|
chrono_tz::UTC,
|
||||||
|
)?;
|
||||||
let now = Utc::now();
|
let now = Utc::now();
|
||||||
|
|
||||||
let mut tasks: Vec<LocalizedShard> = find_shard_by_position(&all_shards, "task", "open")
|
let mut tasks: Vec<LocalizedShard> = find_shard_by_position(&all_shards, "task", "open")
|
||||||
|
|
@ -92,13 +72,19 @@ pub fn run_edit(number: usize) -> Result<(), StreamdError> {
|
||||||
.get("file")
|
.get("file")
|
||||||
.ok_or(StreamdError::MissingFilePath)?;
|
.ok_or(StreamdError::MissingFilePath)?;
|
||||||
|
|
||||||
let editor = std::env::var("EDITOR").unwrap_or_else(|_| "vi".to_string());
|
let editor = std::env::var("EDITOR").unwrap_or_else(|_| {
|
||||||
let line_arg = format!("+{}", task.start_line);
|
if cfg!(windows) {
|
||||||
|
"notepad".to_string()
|
||||||
|
} else {
|
||||||
|
"vi".to_string()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let status = Command::new(&editor)
|
let mut cmd = Command::new(&editor);
|
||||||
.arg(&line_arg)
|
if !editor.to_lowercase().contains("notepad") {
|
||||||
.arg(file_path)
|
cmd.arg(format!("+{}", task.start_line));
|
||||||
.status()?;
|
}
|
||||||
|
let status = cmd.arg(file_path).status()?;
|
||||||
|
|
||||||
if !status.success() {
|
if !status.success() {
|
||||||
return Err(StreamdError::IoError(std::io::Error::other(
|
return Err(StreamdError::IoError(std::io::Error::other(
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,10 @@ impl Settings {
|
||||||
fn config_path() -> PathBuf {
|
fn config_path() -> PathBuf {
|
||||||
if let Some(proj_dirs) = ProjectDirs::from("", "", "streamd") {
|
if let Some(proj_dirs) = ProjectDirs::from("", "", "streamd") {
|
||||||
proj_dirs.config_dir().join("config.toml")
|
proj_dirs.config_dir().join("config.toml")
|
||||||
|
} else if let Some(base_dirs) = directories::BaseDirs::new() {
|
||||||
|
base_dirs.config_dir().join("streamd").join("config.toml")
|
||||||
} else {
|
} else {
|
||||||
PathBuf::from("~/.config/streamd/config.toml")
|
PathBuf::from("streamd_config.toml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue