8
8
Boolean ,
9
9
Column ,
10
10
DateTime ,
11
+ Integer ,
11
12
PrimaryKeyConstraint ,
12
13
String ,
13
14
Table ,
14
15
and_ ,
15
16
not_ ,
17
+ update ,
16
18
)
17
19
from sqlalchemy .sql import select
18
20
19
21
from cloudbot import hook
20
22
from cloudbot .event import EventType
23
+ from cloudbot .hook import Priority
21
24
from cloudbot .util import database , timeformat , web
22
25
from cloudbot .util .formatting import gen_markdown_table
23
26
24
- table = Table (
25
- "tells" ,
26
- database .metadata ,
27
- Column ("connection" , String ),
28
- Column ("sender" , String ),
29
- Column ("target" , String ),
30
- Column ("message" , String ),
31
- Column ("is_read" , Boolean ),
32
- Column ("time_sent" , DateTime ),
33
- Column ("time_read" , DateTime ),
34
- )
27
+
28
+ class TellMessage (database .Base ):
29
+ __tablename__ = "tell_messages"
30
+
31
+ msg_id = Column (Integer , primary_key = True , autoincrement = True )
32
+ conn = Column (String , index = True )
33
+ sender = Column (String )
34
+ target = Column (String , index = True )
35
+ message = Column (String )
36
+ is_read = Column (Boolean , default = False , index = True )
37
+ time_sent = Column (DateTime )
38
+ time_read = Column (DateTime )
39
+
40
+ def format_for_message (self ):
41
+ reltime = timeformat .time_since (self .time_sent )
42
+ return f"{ self .sender } sent you a message { reltime } ago: { self .message } "
43
+
44
+ def mark_read (self , now = None ):
45
+ if now is None :
46
+ now = datetime .now ()
47
+
48
+ self .is_read = True
49
+ self .time_read = now
50
+
35
51
36
52
disable_table = Table (
37
53
"tell_ignores" ,
60
76
tell_cache : List [Tuple [str , str ]] = []
61
77
62
78
79
+ @hook .on_start (priority = Priority .HIGHEST )
80
+ def migrate_tables (db ):
81
+ table = Table (
82
+ "tells" ,
83
+ database .metadata ,
84
+ Column ("connection" , String ),
85
+ Column ("sender" , String ),
86
+ Column ("target" , String ),
87
+ Column ("message" , String ),
88
+ Column ("is_read" , Boolean ),
89
+ Column ("time_sent" , DateTime ),
90
+ Column ("time_read" , DateTime ),
91
+ )
92
+
93
+ if not table .exists (db .bind ):
94
+ return
95
+
96
+ if TellMessage .__table__ .exists (db .bin ):
97
+ raise Exception (
98
+ f"Can't migrate table { table .name } to { TellMessage .__table__ .name } , destination already exists"
99
+ )
100
+
101
+ data = db .execute (table .select ())
102
+ db .bulk_insert_mappings (TellMessage , data , return_defaults = True )
103
+ db .commit ()
104
+ table .drop (db .bind )
105
+
106
+
63
107
@hook .on_start ()
64
108
def load_cache (db ):
65
109
new_cache = []
66
- for row in db .execute (table .select ().where (not_ (table .c .is_read ))):
67
- conn = row ["connection" ]
68
- target = row ["target" ]
110
+ for conn , target in db .execute (
111
+ select (
112
+ [TellMessage .conn , TellMessage .target ], not_ (TellMessage .is_read )
113
+ )
114
+ ):
69
115
new_cache .append ((conn , target ))
70
116
71
117
tell_cache .clear ()
@@ -183,48 +229,35 @@ def list_ignores(conn, nick):
183
229
yield mask
184
230
185
231
186
- def get_unread (db , server , target ):
232
+ def get_unread (db , server , target ) -> List [ TellMessage ] :
187
233
query = (
188
- select ([ table . c . sender , table . c . message , table . c . time_sent ] )
189
- .where (table . c . connection == server . lower ( ))
190
- .where (table . c . target == target . lower () )
191
- .where (not_ ( table . c . is_read ))
192
- .order_by (table . c .time_sent )
234
+ select (TellMessage )
235
+ .where (not_ ( TellMessage . is_read ))
236
+ .where (TellMessage . conn == server )
237
+ .where (TellMessage . target == target . lower ( ))
238
+ .order_by (TellMessage .time_sent )
193
239
)
194
- return db .execute (query ).fetchall ()
240
+
241
+ return db .execute (query ).scalars ().all ()
195
242
196
243
197
244
def count_unread (db , server , target ):
198
245
query = (
199
- select ([sa .func .count ()])
200
- .select_from (table )
201
- .where (table .c .connection == server .lower ())
202
- .where (table .c .target == target .lower ())
203
- .where (not_ (table .c .is_read ))
246
+ select (sa .func .count (TellMessage .msg_id ))
247
+ .where (TellMessage .conn == server .lower ())
248
+ .where (TellMessage .target == target .lower ())
249
+ .where (not_ (TellMessage .is_read ))
204
250
)
205
251
206
252
return db .execute (query ).fetchone ()[0 ]
207
253
208
254
209
255
def read_all_tells (db , server , target ):
210
256
query = (
211
- table .update ()
212
- .where (table .c .connection == server .lower ())
213
- .where (table .c .target == target .lower ())
214
- .where (not_ (table .c .is_read ))
215
- .values (is_read = True )
216
- )
217
- db .execute (query )
218
- db .commit ()
219
- load_cache (db )
220
-
221
-
222
- def read_tell (db , server , target , message ):
223
- query = (
224
- table .update ()
225
- .where (table .c .connection == server .lower ())
226
- .where (table .c .target == target .lower ())
227
- .where (table .c .message == message )
257
+ update (TellMessage )
258
+ .where (TellMessage .conn == server .lower ())
259
+ .where (TellMessage .target == target .lower ())
260
+ .where (TellMessage .is_read .is_ (False ))
228
261
.values (is_read = True )
229
262
)
230
263
db .execute (query )
@@ -233,15 +266,14 @@ def read_tell(db, server, target, message):
233
266
234
267
235
268
def add_tell (db , server , sender , target , message ):
236
- query = table . insert (). values (
237
- connection = server .lower (),
269
+ new_tell = TellMessage (
270
+ conn = server .lower (),
238
271
sender = sender .lower (),
239
272
target = target .lower (),
240
273
message = message ,
241
- is_read = False ,
242
- time_sent = datetime .today (),
274
+ time_sent = datetime .now (),
243
275
)
244
- db .execute ( query )
276
+ db .add ( new_tell )
245
277
db .commit ()
246
278
load_cache (db )
247
279
@@ -267,20 +299,18 @@ def tellinput(conn, db, nick, notice, content):
267
299
if not tells :
268
300
return
269
301
270
- user_from , message , time_sent = tells [0 ]
271
- reltime = timeformat .time_since (time_sent )
272
- reply = "{} sent you a message {} ago: {}" .format (
273
- user_from , reltime , message
274
- )
302
+ first_tell = tells [0 ]
303
+ reply = first_tell .format_for_message ()
275
304
276
305
if len (tells ) > 1 :
277
306
reply += " (+{} more, {}showtells to view)" .format (
278
307
len (tells ) - 1 , conn .config ["command_prefix" ][0 ]
279
308
)
280
309
281
- read_tell (db , conn .name , nick , message )
282
310
notice (reply )
283
311
312
+ first_tell .mark_read ()
313
+
284
314
285
315
@hook .command (autohelp = False )
286
316
def showtells (nick , notice , db , conn ):
@@ -293,9 +323,7 @@ def showtells(nick, notice, db, conn):
293
323
return
294
324
295
325
for tell in tells :
296
- sender , message , time_sent = tell
297
- past = timeformat .time_since (time_sent )
298
- notice ("{} sent you a message {} ago: {}" .format (sender , past , message ))
326
+ notice (tell .format_for_message ())
299
327
300
328
read_all_tells (db , conn .name , nick )
301
329
0 commit comments