Skip to content

Commit d3a79b5

Browse files
Merge pull request #21 from tomokinakamaru/fix-loader
Fix loader
2 parents ec63198 + 408378e commit d3a79b5

File tree

5 files changed

+89
-94
lines changed

5 files changed

+89
-94
lines changed

redspot/datafilters.py

Lines changed: 0 additions & 73 deletions
This file was deleted.

redspot/dataloader.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,21 @@
11
from collections import defaultdict
22

3-
from redspot import database, datafilters
3+
from redspot import database
44
from redspot.notebook import Notebook
55

66

77
def load(path):
8-
stream = _load(path)
9-
stream = datafilters.filter_by_kind(stream)
10-
stream = datafilters.filter_by_diff(stream)
11-
stream = datafilters.filter_void(stream)
12-
yield from stream
13-
14-
15-
def _load(path):
168
panel_roots = _load_panel_roots(path)
17-
for panel, kind, args, notebook in _load_notebooks(path):
9+
for time, panel, kind, args, notebook in _load_notebooks(path):
1810
panel = panel_roots[panel]
19-
yield panel, kind, args, notebook
11+
yield time, panel, kind, args, notebook
2012

2113

2214
def _load_notebooks(path):
2315
notebooks = defaultdict(Notebook)
24-
for _, panel, kind, args in database.get(path):
16+
for time, panel, kind, args in database.get(path):
2517
notebooks[panel].apply(kind, args)
26-
yield panel, kind, args, notebooks[panel]
18+
yield time, panel, kind, args, notebooks[panel]
2719

2820

2921
def _load_panel_roots(path):

redspot/notebook.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ def apply(self, kind, args):
1010
head = kind.split(".", 1)[0]
1111
self._invoke(head, kind, args)
1212

13+
def get_cell(self, id):
14+
for c in self["cells"]:
15+
if c["id"] == id:
16+
return c
17+
1318
def _INotebookModel(self, kind, args):
1419
self._invoke(kind, args)
1520

1621
def _ISharedCell(self, kind, args):
17-
cell = self._get_cell(args["cell"])
22+
cell = self.get_cell(args["cell"])
1823
self._invoke(kind, cell, args)
1924

2025
def _INotebookModel_changed_cellsChange(self, args):
@@ -47,11 +52,6 @@ def _invoke(self, key, *args):
4752
func = getattr(self, f"_{name}", None)
4853
func and func(*args)
4954

50-
def _get_cell(self, id):
51-
for c in self["cells"]:
52-
if c["id"] == id:
53-
return c
54-
5555

5656
def _apply_delta(obj, args):
5757
head = 0

redspot/replay.py

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,94 @@
11
from collections import defaultdict
2+
from copy import deepcopy
23
from datetime import datetime
34
from itertools import count
45
from json import dumps
56

7+
from nbdime import diff
8+
69
from redspot import load
710

811

912
def main(path, outdir):
1013
counters = defaultdict(count)
11-
for panel, data in load(path):
14+
stream = load(path)
15+
stream = _filter_by_kind(stream)
16+
stream = _filter_by_diff(stream)
17+
stream = _filter_void(stream)
18+
for panel, data in stream:
1219
time, uuid = panel.split("-")
1320
ymdt = datetime.fromtimestamp(int(time) / 1000)
1421
outd = outdir / datetime.strftime(ymdt, f"%Y-%m%d-%H%M_{uuid}")
1522
name = f"{next(counters[panel])}.ipynb"
1623
outd.mkdir(parents=True, exist_ok=True)
1724
(outd / name).write_text(dumps(data))
1825
return 0
26+
27+
28+
def _filter_void(stream):
29+
prev = defaultdict(lambda: None)
30+
void = defaultdict(lambda: True)
31+
for panel, notebook in stream:
32+
if panel in prev:
33+
void[panel] = False
34+
yield panel, prev[panel]
35+
prev[panel] = deepcopy(notebook)
36+
for panel, notebook in prev.items():
37+
if not void[panel]:
38+
yield panel, notebook
39+
40+
41+
def _filter_by_diff(stream):
42+
notebooks = defaultdict(lambda: {"cells": [], "metadata": {}})
43+
for panel, notebook in stream:
44+
delta = diff(notebooks[panel], notebook)
45+
notebooks[panel] = deepcopy(notebook)
46+
if _has_visible_change(delta):
47+
yield panel, notebook
48+
49+
50+
def _filter_by_kind(stream):
51+
notebooks = {}
52+
cell_changed = _cell_change_detector()
53+
for _, panel, kind, args, notebook in stream:
54+
notebooks[panel] = notebook
55+
if kind in _yield_immediately:
56+
yield panel, notebooks.pop(panel)
57+
elif kind in _yield_if_cell_changed:
58+
if cell_changed(panel, args):
59+
yield panel, notebooks.pop(panel)
60+
yield from notebooks.items()
61+
62+
63+
def _has_visible_change(delta):
64+
for eps in delta:
65+
op, key = eps["op"], eps["key"]
66+
if op == "patch" and key == "cells":
67+
return True
68+
return False
69+
70+
71+
def _cell_change_detector():
72+
def _(panel, args):
73+
if panel in prev:
74+
new = args.get("cell")
75+
old = prev[panel]
76+
if old != new:
77+
prev[panel] = new
78+
return True
79+
return False
80+
81+
prev = {}
82+
return _
83+
84+
85+
_yield_immediately = (
86+
"INotebookModel.changed:cellsChange",
87+
"ISharedCell.changed:executionCountChange",
88+
)
89+
90+
_yield_if_cell_changed = (
91+
"ISharedCell.changed:attachmentsChange",
92+
"ISharedCell.changed:outputsChange",
93+
"ISharedCell.changed:sourceChange",
94+
)

tests/tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
def test_load_api():
1515
g = redspot.load(database)
16-
assert len(list(g)) == 3
16+
assert len(list(g)) == 16
1717

1818

1919
def test_load_cli():

0 commit comments

Comments
 (0)