Skip to content

Commit 64463bc

Browse files
authored
Merge pull request #109 from ActivityWatch/dev/get-single-event-by-id
2 parents 0629e84 + a0814b0 commit 64463bc

File tree

11 files changed

+322
-166
lines changed

11 files changed

+322
-166
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ typecheck:
1818
typecheck-strict:
1919
export MYPYPATH=./stubs; python -m mypy aw_core aw_datastore aw_transform aw_query --strict-optional --check-untyped-defs; echo "Not a failing step"
2020

21-
PYFILES=aw_core/**.py aw_datastore/**.py aw_query/**.py aw_transform/**.py
21+
PYFILES=$(shell find . -type f -name '*.py')
2222

2323
lint-fix:
24-
pyupgrade --py37-plus ${PYFILES}
24+
pyupgrade --py37-plus ${PYFILES} && true
2525
black ${PYFILES}
2626

2727
clean:

aw_datastore/datastore.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ def get(
102102
self.bucket_id, limit, starttime, endtime
103103
)
104104

105+
def get_by_id(self, event_id) -> Event:
106+
return self.ds.storage_strategy.get_event(self.bucket_id, event_id)
107+
105108
def get_eventcount(
106109
self, starttime: datetime = None, endtime: datetime = None
107110
) -> int:

aw_datastore/storages/abstract.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ def delete_bucket(self, bucket_id: str) -> None:
4242
def get_metadata(self, bucket_id: str) -> dict:
4343
raise NotImplementedError
4444

45+
@abstractmethod
46+
def get_event(
47+
self,
48+
bucket_id: str,
49+
event_id: int,
50+
) -> Event:
51+
raise NotImplementedError
52+
4553
@abstractmethod
4654
def get_events(
4755
self,

aw_datastore/storages/memory.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ def buckets(self):
4949
buckets[bucket_id] = self.get_metadata(bucket_id)
5050
return buckets
5151

52+
def get_event(
53+
self,
54+
bucket_id: str,
55+
event_id: int,
56+
) -> Event:
57+
event = self._get_event(bucket_id, event_id)
58+
return copy.deepcopy(event)
59+
5260
def get_events(
5361
self,
5462
bucket: str,
@@ -117,6 +125,15 @@ def delete(self, bucket_id, event_id):
117125
return True
118126
return False
119127

128+
def _get_event(self, bucket_id, event_id):
129+
events = [
130+
event
131+
for idx, event in reversed(list(enumerate(self.db[bucket_id])))
132+
if event.id == event_id
133+
]
134+
assert len(events) == 1
135+
return events[0]
136+
120137
def replace(self, bucket_id, event_id, event):
121138
for idx in (
122139
idx

aw_datastore/storages/mongodb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def get_events(
9999
if limit == 0:
100100
return []
101101
elif limit < 0:
102-
limit = 10 ** 9
102+
limit = 10**9
103103
ds_events = list(
104104
self.db[bucket_id]["events"]
105105
.find(query_filter)

aw_datastore/storages/peewee.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,17 @@ def replace(self, bucket_id, event_id, event):
254254
event.id = e.id
255255
return event
256256

257+
def get_event(
258+
self,
259+
bucket_id: str,
260+
event_id: int,
261+
):
262+
"""
263+
Fetch a single event from a bucket.
264+
"""
265+
res = self._get_event(bucket_id, event_id)
266+
return Event(**EventModel.json(res))
267+
257268
def get_events(
258269
self,
259270
bucket_id: str,

aw_datastore/storages/sqlite.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional, List
1+
from typing import Optional, List, Iterable
22
from datetime import datetime, timezone, timedelta
33
import json
44
import os
@@ -16,7 +16,7 @@
1616
LATEST_VERSION = 1
1717

1818
# The max integer value in SQLite is signed 8 Bytes / 64 bits
19-
MAX_TIMESTAMP = 2 ** 63 - 1
19+
MAX_TIMESTAMP = 2**63 - 1
2020

2121
CREATE_BUCKETS_TABLE = """
2222
CREATE TABLE IF NOT EXISTS buckets (
@@ -54,6 +54,18 @@
5454
"""
5555

5656

57+
def _rows_to_events(rows: Iterable) -> List[Event]:
58+
events = []
59+
for row in rows:
60+
eid = row[0]
61+
starttime = datetime.fromtimestamp(row[1] / 1000000, timezone.utc)
62+
endtime = datetime.fromtimestamp(row[2] / 1000000, timezone.utc)
63+
duration = endtime - starttime
64+
data = json.loads(row[3])
65+
events.append(Event(id=eid, timestamp=starttime, duration=duration, data=data))
66+
return events
67+
68+
5769
class SqliteStorage(AbstractStorage):
5870
sid = "sqlite"
5971

@@ -256,6 +268,23 @@ def replace(self, bucket_id, event_id, event) -> bool:
256268
self.conditional_commit(1)
257269
return True
258270

271+
def get_event(
272+
self,
273+
bucket_id: str,
274+
event_id: int,
275+
) -> Event:
276+
self.commit()
277+
c = self.conn.cursor()
278+
query = """
279+
SELECT id, starttime, endtime, datastr
280+
FROM events
281+
WHERE bucketrow = (SELECT rowid FROM buckets WHERE id = ?) AND id = ?
282+
LIMIT 1
283+
"""
284+
rows = c.execute(query, [bucket_id, event_id])
285+
events = _rows_to_events(rows)
286+
return events[0]
287+
259288
def get_events(
260289
self,
261290
bucket_id: str,
@@ -279,16 +308,7 @@ def get_events(
279308
ORDER BY endtime DESC LIMIT ?
280309
"""
281310
rows = c.execute(query, [bucket_id, starttime_i, endtime_i, limit])
282-
events = []
283-
for row in rows:
284-
eid = row[0]
285-
starttime = datetime.fromtimestamp(row[1] / 1000000, timezone.utc)
286-
endtime = datetime.fromtimestamp(row[2] / 1000000, timezone.utc)
287-
duration = endtime - starttime
288-
data = json.loads(row[3])
289-
events.append(
290-
Event(id=eid, timestamp=starttime, duration=duration, data=data)
291-
)
311+
events = _rows_to_events(rows)
292312
return events
293313

294314
def get_eventcount(

0 commit comments

Comments
 (0)