forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadvice.py
More file actions
120 lines (101 loc) · 3.82 KB
/
Copy pathadvice.py
File metadata and controls
120 lines (101 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""Advice — proactive coaching items.
Collection: users/{uid}/advice
"""
import logging
import uuid
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional, cast
from google.api_core.exceptions import NotFound
from google.cloud import firestore
from google.cloud.firestore_v1.base_query import FieldFilter
from ._client import db
logger = logging.getLogger(__name__)
BATCH_LIMIT = 500 # Firestore hard limit
def _user_col(uid: str, collection: str) -> Any:
"""Shorthand for users/{uid}/{collection}."""
return db.collection('users').document(uid).collection(collection)
def create_advice(uid: str, content: str, category: str = 'other', **kwargs: Any) -> Dict[str, Any]:
advice_id = str(uuid.uuid4())
now = datetime.now(timezone.utc)
doc: Dict[str, Any] = {
'id': advice_id,
'content': content,
'category': category,
'reasoning': kwargs.get('reasoning'),
'source_app': kwargs.get('source_app'),
'confidence': kwargs.get('confidence', 0.5),
'context_summary': kwargs.get('context_summary'),
'current_activity': kwargs.get('current_activity'),
'created_at': now,
'updated_at': now,
'is_read': False,
'is_dismissed': False,
}
_user_col(uid, 'advice').document(advice_id).set(doc)
return doc
def get_advice(
uid: str, category: Optional[str] = None, limit: int = 50, offset: int = 0, include_dismissed: bool = False
) -> List[Dict[str, Any]]:
col = _user_col(uid, 'advice')
query = col.order_by('created_at', direction=firestore.Query.DESCENDING)
if category:
query = query.where(filter=FieldFilter('category', '==', category))
if not include_dismissed:
query = query.where(filter=FieldFilter('is_dismissed', '==', False))
if offset > 0:
query = query.offset(offset)
query = query.limit(limit)
items: List[Dict[str, Any]] = []
for doc in query.stream():
raw: object = doc.to_dict()
data: Dict[str, Any] = cast(Dict[str, Any], raw) if isinstance(raw, dict) else {}
data['id'] = doc.id
items.append(data)
return items
def update_advice(
uid: str, advice_id: str, is_read: Optional[bool] = None, is_dismissed: Optional[bool] = None
) -> Optional[Dict[str, Any]]:
ref = _user_col(uid, 'advice').document(advice_id)
snap = ref.get()
if not getattr(snap, "exists", False):
return None
updates: Dict[str, Any] = {'updated_at': datetime.now(timezone.utc)}
if is_read is not None:
updates['is_read'] = is_read
if is_dismissed is not None:
updates['is_dismissed'] = is_dismissed
try:
ref.update(updates)
except NotFound:
# The advice was deleted between the existence check and the update.
return None
raw: object = ref.get().to_dict()
if raw is None:
# The advice was deleted between the update and the re-read.
return None
result: Dict[str, Any] = cast(Dict[str, Any], raw) if isinstance(raw, dict) else {}
result['id'] = advice_id
return result
def delete_advice(uid: str, advice_id: str) -> bool:
ref = _user_col(uid, 'advice').document(advice_id)
if not getattr(ref.get(), "exists", False):
return False
ref.delete()
return True
def mark_all_advice_read(uid: str) -> int:
col = _user_col(uid, 'advice')
query = col.where(filter=FieldFilter('is_read', '==', False))
batch = db.batch()
total = 0
batch_count = 0
for doc in query.stream():
batch.update(col.document(doc.id), {'is_read': True, 'updated_at': datetime.now(timezone.utc)})
total += 1
batch_count += 1
if batch_count >= BATCH_LIMIT:
batch.commit()
batch = db.batch()
batch_count = 0
if batch_count > 0:
batch.commit()
return total