Add log-work-expense skill to skill index
This commit is contained in:
parent
e667cf0e39
commit
ac1b4f83f3
4 changed files with 161 additions and 0 deletions
53
log-work-expense/scripts/classify_image.py
Normal file
53
log-work-expense/scripts/classify_image.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Classify an image as 'receipt' or 'odometer'.
|
||||
|
||||
Usage:
|
||||
python classify_image.py <image_path>
|
||||
|
||||
Prints exactly one word: "receipt" or "odometer"
|
||||
"""
|
||||
|
||||
import sys
|
||||
import base64
|
||||
import requests
|
||||
|
||||
API_KEY = "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"
|
||||
MODEL = "google/gemini-2.5-flash-lite"
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: classify_image.py <image_path>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
path = sys.argv[1]
|
||||
with open(path, "rb") as f:
|
||||
b64 = base64.b64encode(f.read()).decode()
|
||||
|
||||
ext = path.rsplit(".", 1)[-1].lower()
|
||||
mime = "image/jpeg" if ext in ("jpg", "jpeg") else "image/png"
|
||||
|
||||
resp = requests.post(
|
||||
"https://openrouter.ai/api/v1/chat/completions",
|
||||
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
|
||||
json={
|
||||
"model": MODEL,
|
||||
"messages": [{"role": "user", "content": [
|
||||
{"type": "text", "text": "Classify this image. Reply with exactly one word: receipt or odometer. Nothing else."},
|
||||
{"type": "image_url", "image_url": {"url": f"data:{mime};base64,{b64}"}}
|
||||
]}],
|
||||
"max_tokens": 10
|
||||
},
|
||||
timeout=30,
|
||||
)
|
||||
|
||||
text = resp.json()["choices"][0]["message"]["content"].strip().lower()
|
||||
if "receipt" in text:
|
||||
print("receipt")
|
||||
elif "odometer" in text:
|
||||
print("odometer")
|
||||
else:
|
||||
print(f"unknown: {text}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
62
log-work-expense/scripts/log_expense.py
Normal file
62
log-work-expense/scripts/log_expense.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Log work expenses to MongoDB (wip.work_expenses).
|
||||
|
||||
Usage:
|
||||
python log_expense.py <type> <account> <date> <note> <s2_url_1> [s2_url_2]
|
||||
|
||||
type: "meal" or "mileage"
|
||||
account: e.g. "LTISD"
|
||||
date: YYYY-MM-DD
|
||||
note: free-text context (quote if it has spaces)
|
||||
s2_url: one or more S2 URLs of uploaded files
|
||||
|
||||
Rules enforced:
|
||||
- meal: exactly 1 file per invocation
|
||||
- mileage: exactly 2 files per invocation (start + end odometer)
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pymongo import MongoClient
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
if len(args) < 5:
|
||||
print("Usage: log_expense.py <type> <account> <date> <note> <s2_url_1> [s2_url_2]")
|
||||
sys.exit(1)
|
||||
|
||||
exp_type = args[0]
|
||||
account = args[1]
|
||||
date = args[2]
|
||||
note = args[3]
|
||||
files = args[4:]
|
||||
|
||||
if exp_type not in ("meal", "mileage"):
|
||||
print(f"Error: type must be 'meal' or 'mileage', got '{exp_type}'")
|
||||
sys.exit(1)
|
||||
|
||||
if exp_type == "meal" and len(files) != 1:
|
||||
print(f"Error: meal entries must have exactly 1 file, got {len(files)}")
|
||||
sys.exit(1)
|
||||
|
||||
if exp_type == "mileage" and len(files) != 2:
|
||||
print(f"Error: mileage entries must have exactly 2 files (start + end odometer), got {len(files)}")
|
||||
sys.exit(1)
|
||||
|
||||
client = MongoClient("mongodb://root:3wwfoUjyk2E2zWELXFlLuHqfw1ALlOp4pb2H5Vq3TImbMIHL2h1u8Jej2mjzCPl@docdb.connorrhodes.com:35563")
|
||||
db = client["wip"]
|
||||
col = db["work_expenses"]
|
||||
|
||||
doc = {
|
||||
"files": files,
|
||||
"date": date,
|
||||
"type": exp_type,
|
||||
"account": account,
|
||||
"note": note,
|
||||
"status": "todo"
|
||||
}
|
||||
|
||||
result = col.insert_one(doc)
|
||||
print(f"Inserted {exp_type} for {account} on {date}: {result.inserted_id}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue