7
7
import time
8
8
import asyncio
9
9
from functools import partial
10
- from typing import Any , Callable , Dict , List , Set
11
- from uuid import uuid4
12
-
13
10
from jupyter_ydoc .ybasedoc import YBaseDoc
11
+ from typing import Any , Callable , Set
12
+ from uuid import uuid4
14
13
from pycrdt import Array , ArrayEvent , Map , MapEvent
15
14
16
15
@@ -42,40 +41,91 @@ def create_task(self, coro):
42
41
task .add_done_callback (self ._background_tasks .discard )
43
42
44
43
@property
45
- def messages (self ) -> List :
46
- return self ._ymessages . to_py ()
44
+ def ymessages (self ) -> Array :
45
+ return self ._ymessages
47
46
48
47
@property
49
- def users (self ) -> Map :
50
- return self ._yusers . to_py ()
48
+ def yusers (self ) -> Map :
49
+ return self ._yusers
51
50
52
51
@property
53
- def metadata (self ) -> Map :
54
- return self ._ymetadata .to_py ()
52
+ def ymetadata (self ) -> Map :
53
+ return self ._ymetadata
54
+
55
+ def get_user (self , username : str ) -> dict [str , str ] | None :
56
+ """
57
+ Returns a message from its id, or None
58
+ """
59
+ return self .get_users ().get (username , None )
55
60
56
- def get_users (self ) -> Dict :
61
+ def get_user_by_name (self , name : str ) -> dict [str , str ] | None :
62
+ """
63
+ Returns a user from its name property, or None.
64
+ """
65
+ return next (
66
+ (user for user in self .get_users ().values () if user ["name" ] == name ),
67
+ None
68
+ )
69
+
70
+ def get_users (self ) -> dict [str , dict [str , str ]]:
57
71
"""
58
72
Returns the users of the document.
59
73
:return: Document's users.
60
- :rtype: string
61
74
"""
75
+ return self ._yusers .to_py ()
76
+
77
+ def set_user (self , user : dict [str , str ]) -> None :
78
+ """
79
+ Adds or modifies a user.
80
+ """
81
+ with self ._ydoc .transaction ():
82
+ self ._yusers .update ({user ["username" ]: user })
62
83
63
- users = self ._yusers .to_py ()
64
- return dict (users = users )
84
+ def get_message (self , id : str ) -> dict | None :
85
+ """
86
+ Returns a message from its id, or None
87
+ """
88
+ return next (
89
+ (msg for msg in self .get_messages () if msg ["id" ] == id ),
90
+ None
91
+ )
65
92
66
- def get_messages (self ) -> Dict :
93
+ def get_messages (self ) -> list [ dict ] :
67
94
"""
68
95
Returns the messages of the document.
69
96
:return: Document's messages.
70
- :rtype: string
71
97
"""
98
+ return self ._ymessages .to_py ()
99
+
100
+ def add_message (self , message : dict ) -> None :
101
+ """
102
+ Appends a message to the document.
103
+ """
104
+ with self ._ydoc .transaction ():
105
+ self ._ymessages .append (message )
106
+
107
+ def get_single_metadata (self , name ) -> dict :
108
+ """
109
+ Return a single metadata.
110
+ """
111
+ return self .get_metadata ().get (name , {})
72
112
73
- messages = self ._ymessages .to_py ()
74
- return dict (messages = messages )
113
+ def get_metadata (self ) -> dict [str , dict ]:
114
+ """
115
+ Returns the metadata of the document.
116
+ """
117
+ return self ._ymetadata .to_py ()
118
+
119
+ def set_metadata (self , name : str , metadata : dict ):
120
+ """
121
+ Adds or modifies a metadata of the document.
122
+ """
123
+ with self ._ydoc .transaction ():
124
+ self ._ymetadata .update ({name : metadata })
75
125
76
126
async def create_id (self ) -> str :
77
127
"""
78
- Create a new ID for the document.
128
+ Creates a new ID for the document.
79
129
"""
80
130
id = str (uuid4 ())
81
131
self .set_id (id )
@@ -97,13 +147,12 @@ def set_id(self, id: str) -> None:
97
147
def get (self ) -> str :
98
148
"""
99
149
Returns the contents of the document.
100
- :return: Document's contents.
101
- :rtype: string
150
+ :return: Document's contents in JSON.
102
151
"""
103
152
return json .dumps ({
104
- "messages" : self .messages ,
105
- "users" : self .users ,
106
- "metadata" : self .metadata
153
+ "messages" : self .get_messages () ,
154
+ "users" : self .get_users () ,
155
+ "metadata" : self .get_metadata ()
107
156
})
108
157
109
158
def set (self , value : str ) -> None :
@@ -209,7 +258,7 @@ async def _set_timestamp(self, msg_idx: int, timestamp: float):
209
258
# should be the last one.
210
259
# The next() function below return the index of the first message with a timestamp inferior of the
211
260
# current one, starting from the end of the list.
212
- new_idx = len (self ._ymessages ) - next ((i for i , v in enumerate (self ._ymessages . to_py ()[::- 1 ]) if v ["time" ] < timestamp ), len (self ._ymessages ))
261
+ new_idx = len (self ._ymessages ) - next ((i for i , v in enumerate (self .get_messages ()[::- 1 ]) if v ["time" ] < timestamp ), len (self ._ymessages ))
213
262
if msg_idx != new_idx :
214
263
message = self ._ymessages .pop (msg_idx )
215
264
self ._ymessages .insert (new_idx , message )
0 commit comments