Skip to content

Commit c7cbefb

Browse files
committed
Merge branch 'feat/advancedFiltering'
2 parents 88e46cb + a32bef5 commit c7cbefb

2 files changed

Lines changed: 206 additions & 2 deletions

File tree

cmd/config.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,12 @@ type LoadEnvConfig struct {
107107
** @return LoadEnvConfig - Configuration result with logger and any validation error
108108
**************************************************************************************************/
109109
func LoadEnvForTesting() LoadEnvConfig {
110-
_ = godotenv.Load()
111-
logger := configureLogger()
110+
godotenv.Load()
112111

112+
logger := configureLogger()
113+
if criteria == "" {
114+
criteria = os.Getenv("CRITERIA")
115+
}
113116
if apiKey == "" {
114117
apiKey = os.Getenv("API_KEY")
115118
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# What’s New: Advanced Filtering & Safer Grouping
2+
3+
This branch introduces easier, more powerful ways to tell Immich Stack how to group your photos into stacks — with simple, copy‑pasteable examples. It focuses on new capabilities; no test/refactor details here.
4+
5+
## Highlights
6+
7+
- Expression‑based criteria: combine rules with AND / OR / NOT
8+
- Flexible groups: per‑group AND/OR logic (independent OR criteria)
9+
- Safer regex: no match = not grouped by that rule (prevents stray stacks)
10+
- CLI flag precedence: `--criteria` overrides `CRITERIA` env
11+
- Better logs: clearer mode banners and per‑asset context when debugging
12+
13+
## 1) Expression‑Based Criteria (AND / OR / NOT)
14+
15+
You can now describe complex logic for grouping in one place. Expressions let you nest conditions and mix operators.
16+
17+
Example: group photos if the filename starts with PXL or IMG, and were taken within 2 seconds of each other.
18+
19+
```json
20+
{
21+
"mode": "advanced",
22+
"expression": {
23+
"operator": "AND",
24+
"children": [
25+
{
26+
"operator": "OR",
27+
"children": [
28+
{
29+
"criteria": {
30+
"key": "originalFileName",
31+
"regex": { "key": "^PXL_", "index": 0 }
32+
}
33+
},
34+
{
35+
"criteria": {
36+
"key": "originalFileName",
37+
"regex": { "key": "^IMG_", "index": 0 }
38+
}
39+
}
40+
]
41+
},
42+
{
43+
"criteria": {
44+
"key": "localDateTime",
45+
"delta": { "milliseconds": 2000 }
46+
}
47+
}
48+
]
49+
}
50+
}
51+
```
52+
53+
Why it’s useful:
54+
55+
- Mix camera types and time windows in one rule
56+
- Exclude things with `NOT` (e.g., not archived)
57+
- Build exactly the grouping logic you want
58+
59+
## 2) Flexible Groups (Independent OR Criteria)
60+
61+
Prefer simpler building blocks? You can still use “groups” with an operator for that group. This is great for “match any of these patterns” cases.
62+
63+
Example: group by directory OR by being close in time.
64+
65+
```json
66+
{
67+
"mode": "advanced",
68+
"groups": [
69+
{
70+
"operator": "OR",
71+
"criteria": [
72+
{ "key": "originalPath", "split": { "delimiters": ["/"], "index": 2 } },
73+
{ "key": "localDateTime", "delta": { "milliseconds": 1000 } }
74+
]
75+
}
76+
]
77+
}
78+
```
79+
80+
Why it’s useful:
81+
82+
- Keep rules readable while still allowing OR logic
83+
- Works well for “either same folder OR taken close in time”
84+
85+
## 3) Safer Regex Matching (No Surprise Grouping)
86+
87+
When a regex doesn’t match, that rule contributes no value. Assets won’t get grouped by an unmatched pattern. This prevents accidental stacking from partial or wrong matches.
88+
89+
Tip: Use `index` to grab exactly the part you want (full match = 0; capture group = 1+).
90+
91+
```json
92+
{ "key": "originalFileName", "regex": { "key": "PXL_(\\d{8})", "index": 1 } }
93+
```
94+
95+
## 4) CLI > Env: Explicit Criteria Wins
96+
97+
The `--criteria` flag now wins over the `CRITERIA` environment variable. This makes quick experiments easy.
98+
99+
Examples:
100+
101+
- One‑off run with CLI flag:
102+
103+
```bash
104+
immich-stack \
105+
--api-url "http://immich:3001/api" \
106+
--api-key "$API_KEY" \
107+
--criteria '{"mode":"advanced","groups":[{"operator":"OR","criteria":[{"key":"originalPath","split":{"delimiters":["/"],"index":2}},{"key":"localDateTime","delta":{"milliseconds":1000}}]}]}'
108+
```
109+
110+
- Using `.env`, but override on the command line:
111+
112+
```bash
113+
CRITERIA='{"mode":"advanced","expression":{"operator":"AND","children":[{"criteria":{"key":"originalFileName","regex":{"key":"^IMG_","index":0}}},{"criteria":{"key":"localDateTime","delta":{"milliseconds":1500}}}]}}' \
114+
immich-stack --criteria '{"mode":"advanced","expression":{"operator":"OR","children":[{"criteria":{"key":"originalFileName","regex":{"key":"^PXL_","index":0}}},{"criteria":{"key":"originalFileName","regex":{"key":"^DSC","index":0}}}]}}'
115+
```
116+
117+
## 5) Debugging Is Clearer
118+
119+
Turn on debug logging to see how assets are grouped and why.
120+
121+
```bash
122+
LOG_LEVEL=debug immich-stack --api-url "$API_URL" --api-key "$API_KEY" --criteria '<your json here>'
123+
```
124+
125+
What you’ll notice:
126+
127+
- A banner indicating which mode you’re using (expression vs groups)
128+
- Per‑asset logs with filenames, IDs, and timestamps
129+
- Clear “parent” vs “child” lines for each stack
130+
131+
## Quick Copy/Paste Recipes
132+
133+
- Group by base filename before a `~` or `.`:
134+
135+
```json
136+
[
137+
{
138+
"key": "originalFileName",
139+
"split": { "delimiters": ["~", "."], "index": 0 }
140+
}
141+
]
142+
```
143+
144+
- Group PXL photos taken within 1 second:
145+
146+
```json
147+
{
148+
"mode": "advanced",
149+
"expression": {
150+
"operator": "AND",
151+
"children": [
152+
{
153+
"criteria": {
154+
"key": "originalFileName",
155+
"regex": { "key": "^PXL_", "index": 0 }
156+
}
157+
},
158+
{
159+
"criteria": {
160+
"key": "localDateTime",
161+
"delta": { "milliseconds": 1000 }
162+
}
163+
}
164+
]
165+
}
166+
}
167+
```
168+
169+
- Group by folder name OR within 2 seconds:
170+
171+
```json
172+
{
173+
"mode": "advanced",
174+
"groups": [
175+
{
176+
"operator": "OR",
177+
"criteria": [
178+
{
179+
"key": "originalPath",
180+
"split": { "delimiters": ["/"], "index": 2 }
181+
},
182+
{ "key": "localDateTime", "delta": { "milliseconds": 2000 } }
183+
]
184+
}
185+
]
186+
}
187+
```
188+
189+
- One‑liner `.env` example (paste into your terminal for a single run):
190+
191+
```bash
192+
CRITERIA='[{"key":"originalFileName","split":{"delimiters":["~","."],"index":0}}]' immich-stack --api-url "$API_URL" --api-key "$API_KEY"
193+
```
194+
195+
## Backward Compatibility
196+
197+
- Legacy array format still works as before
198+
- Advanced mode is opt‑in (`{"mode":"advanced": ...}`)
199+
- If you don’t set `mode`, legacy behavior applies
200+
201+
That’s it — more control, safer grouping, and easier runs from the CLI.

0 commit comments

Comments
 (0)