Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b74a7ad
ci: separate some tasks to speed things up
onkoe Jan 19, 2025
8e1b5d4
refactor(search): use `chrono` types over `jiff`
onkoe Jan 19, 2025
574560d
chore(meta): add short todo for video framerate
onkoe Jan 19, 2025
2f8db06
feat(meta/OtherMeta): add constructor for map vals
onkoe Jan 19, 2025
6d9d7d1
style(meta): move imports to top
onkoe Jan 19, 2025
daf9388
refactor(tag): make types more sane
onkoe Jan 19, 2025
089b276
test(feat, tag): add tag ctor for tests
onkoe Jan 19, 2025
7ca3a2c
feat(search/detail): mirror MediaKind w KindDetail
onkoe Jan 19, 2025
0a39b35
refactor(search/detail): use `Uuid` over `String`
onkoe Jan 19, 2025
4fb0f38
feat(search/detail): impl Display for Comparison
onkoe Jan 19, 2025
dcf8c54
fix(search/modf): uhh... use OrientationDetail
onkoe Jan 19, 2025
21debe6
refactor(search/modf/DateTime): remove "During"
onkoe Jan 19, 2025
839a2e3
refactor(search/modf): `sea-query` in `ToQuery`
onkoe Jan 19, 2025
321ad49
refactor(search/query): rewrite with `sea-query`
onkoe Jan 19, 2025
0daaa73
fix(search/query/Literal): add `%` for contains
onkoe Jan 19, 2025
4c0d961
test(fix): use `temp_dir` crate for dir creation
onkoe Jan 19, 2025
e1504b2
fix(meta): use the actual MIME type in its field
onkoe Jan 19, 2025
5882da5
fix(search/query/json): use `cast_json_field`
onkoe Jan 19, 2025
227c8c1
test(search/query): add a metric ****ton of tests
onkoe Jan 19, 2025
23343f3
refactor(test, query): use integration tests
onkoe Jan 20, 2025
7ec9070
feat(db, Media): add `album` field
onkoe Jan 20, 2025
6af78dd
fix(test, search): use uuid for each db path
onkoe Jan 20, 2025
da23b78
test(builder): check that it can find albums right
onkoe Jan 20, 2025
25f46e4
feat(search/query): CollectionMod::Album impl
onkoe Jan 20, 2025
ed5bb68
test(search): collection modifier album
onkoe Jan 20, 2025
d3d1a01
chore(test/file_watcher): use lower sleep times
onkoe Jan 22, 2025
e88c073
refactor(search/details): revert to tags by name
onkoe Jan 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 45 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
fail-fast: false

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install `nasm`
run: sudo apt-get install yasm -y
- name: Install `yasm`
run: sudo apt-get update && sudo apt-get install build-essential yasm -y

- name: Set up Rust toolchain
uses: actions-rs/toolchain@v1
Expand All @@ -47,7 +47,7 @@ jobs:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ matrix.toolchain }}-${{ hashFiles('**/Cargo.lock') }}

- name: Cache cargo bin # bc wow why does it take three minutes to build `cargo-deny`
- name: Cache cargo bin
uses: actions/cache@v4
with:
path: ~/.cargo/bin
Expand All @@ -61,17 +61,50 @@ jobs:
with:
tool: cargo-deny,cargo-nextest,cargo-rdme

- name: Run tests
run: cargo nextest run

- name: Run doctests
run: cargo test --doc

- name: Check for unused dependencies
uses: bnjbvr/cargo-machete@main

- name: Make sure README is up-to-date
run: cargo rdme --check
cargo_deny:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- name: Run cargo-deny
run: cargo deny check
- name: Set up Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Run tests
run: cargo nextest run
- name: Install `cargo` tools to do more testing
uses: taiki-e/install-action@v2
with:
tool: cargo-deny

- name: Run doctests
run: cargo test --doc

readme:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- name: Install `yasm`
run: sudo apt-get update && sudo apt-get install build-essential yasm -y

- name: Set up Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Install `cargo` tools to do more testing
uses: taiki-e/install-action@v2
with:
tool: cargo-rdme

- name: Make sure README is up-to-date
run: cargo rdme --check

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ async-watcher = "0.3.0"
tracing = "0.1.40"
async-walkdir = "2.0.0"
rand = "0.8.5"
# flutter_rust_bridge = "2.3.0" # note: this is to specify acceptable inputs for flutter ffi

# kinda unused rn
jiff = { version = "0.1.13", features = ["serde"] }

# async
tokio = { version = "1.40", features = ["macros", "rt-multi-thread"] }
Expand Down Expand Up @@ -51,6 +47,8 @@ chrono = { version = "0.4.39", features = ["serde"] }
uuid = { version = "1.12.0", features = ["v4", "serde"] }
avif-parse = "1.3.2"
blake3 = { version = "1.5.5", features = ["mmap", "rayon"] }
sea-query = { version = "0.32.1", default-features = false, features = ["derive", "backend-sqlite", "with-chrono", "chrono"] }
sea-query-binder = { version = "0.7.0", features = ["chrono", "runtime-tokio", "sqlx-sqlite", "with-chrono"] }
# crc32fast = "1.4.2"

# sys dependencies
Expand All @@ -71,3 +69,4 @@ tracing-subscriber = "0.3.18"
dirs = "6.0.0"
anyhow = "1.0.95"
console-subscriber = "0.4.1"
temp-dir = "0.1.14"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ To build this, there are a few dependencies you need to install. I use Fedora, b
Under active development.

- [ ] GOAL: Feature-completeness
- [ ] Metadata scanning for `Media`
- [ ] Images
- [x] Metadata scanning for `Media`
- [x] Images
- [ ] GIFS
- [ ] Video
- [ ] General (including Folder. i.e. `stat`)
Expand Down
51 changes: 51 additions & 0 deletions migrations/0004_tables.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-- media info: cached metadata about tracked media files
CREATE TABLE IF NOT EXISTS info(
id TEXT NOT NULL PRIMARY KEY,
-- note: this would preferably be unique, but that messes with modern sqlite
-- update-insert syntax...
path TEXT NOT NULL,
filesize INTEGER NOT NULL,
format TEXT NOT NULL,
creation_date DATETIME,
modification_date DATETIME,
first_seen_date DATETIME NOT NULL,
width_px INTEGER NOT NULL,
height_px INTEGER NOT NULL,
specific_metadata TEXT NOT NULL,
other_metadata TEXT,
tags TEXT NOT NULL
);

ALTER TABLE
info
ADD
COLUMN album TEXT NOT NULL;

-- thumbnails: preview media
CREATE TABLE IF NOT EXISTS thumbnail(
-- path to the thumbnail on disk
path TEXT NOT NULL,
-- thumbnail is for the media file with this uuid
media_id TEXT NOT NULL PRIMARY KEY
);

-- albums: contain media
CREATE TABLE IF NOT EXISTS albums(
id TEXT NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
path TEXT NOT NULL,
--
-- uuids (in json)
contained_media TEXT NOT NULL
);

-- hashes: media file hashes to ensure metadata is up-to-date!
CREATE TABLE IF NOT EXISTS hashes(
media_id TEXT NOT NULL PRIMARY KEY,
hash BLOB NOT NULL
);

-- hash_blob_index: tell SQLite to make a btree for the hashes, too.
--
-- (this allows for high-speed lookups, both ways. hash <=> id)
CREATE UNIQUE INDEX IF NOT EXISTS hash_blob_index ON hashes(hash);
2 changes: 2 additions & 0 deletions src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub static DATABASE: LazyLock<Pool<Sqlite>> = LazyLock::new(|| {
panic!("No database folder path given.");
};

tracing::debug!("Loading from database at `{raves_db_folder}`...");

// ensure the path exists
match raves_db_folder.try_exists() {
Ok(true) => (),
Expand Down
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pub enum RavesError {
error: std::io::Error,
},

#[error("Failed to find media file's parent. path: {_0}")]
MediaFilePathNoParent(Utf8PathBuf),

#[error("The media file at `{path}` does not appear to contain MIME (file type) data.")]
NoMimeData { path: String },

Expand Down
49 changes: 47 additions & 2 deletions src/models/media/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ impl MediaBuilder {
/// 7. Return it.
#[tracing::instrument(skip(self))]
async fn build_internal(mut self, path: &Utf8Path) -> Result<Media, RavesError> {
// before anything, let's make sure the media file has an album to use!
let album = path
.parent()
.map(|p| p.to_path_buf().to_string())
.inspect(|parent| {
tracing::debug!("Found album (parent) for media file! path: {parent}")
})
.ok_or_else(|| {
tracing::warn!("Given a supposed file path, but failed to find its parent!");
RavesError::MediaFilePathNoParent(path.to_path_buf())
})?;

// grab format and apply it to self
let format = format(path).await?;
let mime_type = format.mime_type();
Expand Down Expand Up @@ -184,11 +196,14 @@ impl MediaBuilder {
Ok(Media {
id,

album: album.to_string(),
path: path.to_string(),

filesize: self.filesize.ok_or(RavesError::FileMissingMetadata(
path.to_string(),
"no file size given".into(),
))?,

creation_date: self.creation_date,
modification_date: self.modification_date,

Expand Down Expand Up @@ -342,7 +357,7 @@ pub fn get_video_len(path: &Utf8Path) -> Result<SpecificMetadata, RavesError> {

#[cfg(test)]
mod tests {
use std::env::temp_dir;
use temp_dir::TempDir;

use camino::Utf8PathBuf;
use chrono::{DateTime, Utc};
Expand All @@ -362,9 +377,10 @@ mod tests {
/// The `MediaBuilder` should keep the `id` and `first_seen_date` fields as-is.
#[tokio::test]
async fn media_builder_keeps_static_fields() {
let temp_dir = TempDir::new().unwrap();
// set up the db
database::DB_FOLDER_PATH
.set(Utf8PathBuf::try_from(temp_dir()).unwrap())
.set(Utf8PathBuf::try_from(temp_dir.path().to_path_buf()).unwrap())
.unwrap();

let path = Utf8PathBuf::from("tests/assets/fear.avif")
Expand All @@ -375,6 +391,7 @@ mod tests {
let old_media = Media {
id: Uuid::nil(),
path: path.to_string(),
album: "tests/assets".into(),
filesize: 0,
format: Json(Format::new_from_mime("image/avif").unwrap()),
creation_date: None,
Expand Down Expand Up @@ -425,4 +442,32 @@ mod tests {
"post-insert same first seen dates"
);
}

/// Checks that the `MediaBuilder` can correctly find albums.
#[tokio::test]
async fn album() {
let temp_dir = TempDir::new().unwrap();
let album_path = temp_dir.path().join("farts album");
let file_path = album_path.join("fear.avif");

// make a new folder in the temp_dir called "farts album"
tokio::fs::create_dir_all(temp_dir.path().join("farts album"))
.await
.unwrap();

database::DB_FOLDER_PATH
.set(Utf8PathBuf::try_from(temp_dir.path().to_path_buf()).unwrap())
.unwrap();

tokio::fs::copy("tests/assets/fear.avif", &file_path)
.await
.unwrap();

let media = MediaBuilder::default()
.build(Utf8PathBuf::try_from(file_path).unwrap())
.await
.unwrap();

assert_eq!(media.album, album_path.to_string_lossy().to_string());
}
}
Loading
Loading