reykit 1.0.1__py3-none-any.whl → 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
reywechat/rdatabase.py DELETED
@@ -1,1189 +0,0 @@
1
- # !/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- """
5
- @Time : 2023-10-23 20:55:58
6
- @Author : Rey
7
- @Contact : reyxbo@163.com
8
- @Explain : Database methods.
9
- """
10
-
11
-
12
- from typing import Literal, Union, Optional
13
- from json import loads as json_loads
14
- from reydb.rconnection import RDatabase as RRDatabase
15
- from reykit.rexception import throw
16
- from reykit.ros import RFolder
17
- from reykit.rtime import to_time, time_to, sleep
18
- from reykit.rwrap import wrap_thread
19
-
20
- from .rreceive import RMessage
21
- from .rsend import RSendParam
22
- from .rwechat import RWeChat
23
-
24
-
25
- __all__ = (
26
- 'RDatabase',
27
- )
28
-
29
-
30
- class RDatabase(object):
31
- """
32
- Rey's `database` type.
33
- """
34
-
35
-
36
- def __init__(
37
- self,
38
- rwechat: RWeChat,
39
- rrdatabase: Union[RRDatabase, dict[Literal['wechat', 'file'], RRDatabase]]
40
- ) -> None:
41
- """
42
- Build `database` attributes.
43
-
44
- Parameters
45
- ----------
46
- rwechat : `RClient` instance.
47
- rrdatabase : `RDatabase` instance of `reykit` package.
48
- - `RDatabase`, Set all `RDatabase`: instances.
49
- - `dict`, Set each `RDatabase`: instance, all item is required.
50
- `Key 'wechat'`: `RDatabase` instance used in WeChat methods.
51
- `Key 'file'`: `RDatabase` instance used in file methods.
52
- """
53
-
54
- # Set attribute.
55
- self.rwechat = rwechat
56
- match rrdatabase:
57
- case RRDatabase():
58
- self.rrdatabase_wechat = self.rrdatabase_file = rrdatabase
59
- case dict():
60
- self.rrdatabase_wechat = rrdatabase.get('wechat')
61
- self.rrdatabase_file = rrdatabase.get('file')
62
- if (
63
- self.rrdatabase_wechat
64
- or self.rrdatabase_file
65
- ):
66
- throw(ValueError, rrdatabase)
67
- case _:
68
- throw(TypeError, rrdatabase)
69
-
70
- # Build.
71
- self.build()
72
-
73
- # Add handler.
74
- self._to_contact_user()
75
- self._to_contact_room()
76
- self._to_contact_room_user()
77
- self._to_message_receive()
78
- self._to_message_send()
79
- self._from_message_send_loop()
80
-
81
-
82
- def build(self) -> None:
83
- """
84
- Check and build all standard databases and tables.
85
- """
86
-
87
- # Set parameter.
88
-
89
- ## Database.
90
- databases = [
91
- {
92
- 'database': 'wechat'
93
- }
94
- ]
95
-
96
- ## Table.
97
- tables = [
98
-
99
- ### 'contact_user'.
100
- {
101
- 'path': ('wechat', 'contact_user'),
102
- 'fields': [
103
- {
104
- 'name': 'create_time',
105
- 'type_': 'datetime',
106
- 'constraint': 'NOT NULL DEFAULT CURRENT_TIMESTAMP',
107
- 'comment': 'Record create time.'
108
- },
109
- {
110
- 'name': 'update_time',
111
- 'type_': 'datetime',
112
- 'constraint': 'DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP',
113
- 'comment': 'Record update time.'
114
- },
115
- {
116
- 'name': 'user_id',
117
- 'type_': 'varchar(24)',
118
- 'constraint': 'NOT NULL',
119
- 'comment': 'User ID.'
120
- },
121
- {
122
- 'name': 'name',
123
- 'type_': 'varchar(32)',
124
- 'constraint': 'CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL',
125
- 'comment': 'User name.'
126
- },
127
- {
128
- 'name': 'contact',
129
- 'type_': 'tinyint unsigned',
130
- 'constraint': 'NOT NULL',
131
- 'comment': 'Is the contact, 0 is contact, 1 is no contact.'
132
- },
133
- {
134
- 'name': 'valid',
135
- 'type_': 'tinyint unsigned',
136
- 'constraint': 'DEFAULT 1',
137
- 'comment': 'Is the valid, 0 is invalid, 1 is valid.'
138
- }
139
- ],
140
- 'primary': 'user_id',
141
- 'comment': 'User contact table.'
142
- },
143
-
144
- ### 'contact_room'.
145
- {
146
- 'path': ('wechat', 'contact_room'),
147
- 'fields': [
148
- {
149
- 'name': 'create_time',
150
- 'type_': 'datetime',
151
- 'constraint': 'NOT NULL DEFAULT CURRENT_TIMESTAMP',
152
- 'comment': 'Record create time.'
153
- },
154
- {
155
- 'name': 'update_time',
156
- 'type_': 'datetime',
157
- 'constraint': 'DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP',
158
- 'comment': 'Record update time.'
159
- },
160
- {
161
- 'name': 'room_id',
162
- 'type_': 'varchar(31)',
163
- 'constraint': 'NOT NULL',
164
- 'comment': 'Chat room ID.'
165
- },
166
- {
167
- 'name': 'name',
168
- 'type_': 'varchar(32)',
169
- 'constraint': 'CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL',
170
- 'comment': 'Chat room name.'
171
- },
172
- {
173
- 'name': 'contact',
174
- 'type_': 'tinyint unsigned',
175
- 'constraint': 'NOT NULL',
176
- 'comment': 'Is the contact, 0 is contact, 1 is no contact.'
177
- },
178
- {
179
- 'name': 'valid',
180
- 'type_': 'tinyint unsigned',
181
- 'constraint': 'DEFAULT 1',
182
- 'comment': 'Is the valid, 0 is invalid, 1 is valid.'
183
- }
184
- ],
185
- 'primary': 'room_id',
186
- 'comment': 'Chat room contact table.'
187
- },
188
-
189
- ### 'contact_room_user'.
190
- {
191
- 'path': ('wechat', 'contact_room_user'),
192
- 'fields': [
193
- {
194
- 'name': 'create_time',
195
- 'type_': 'datetime',
196
- 'constraint': 'NOT NULL DEFAULT CURRENT_TIMESTAMP',
197
- 'comment': 'Record create time.'
198
- },
199
- {
200
- 'name': 'update_time',
201
- 'type_': 'datetime',
202
- 'constraint': 'DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP',
203
- 'comment': 'Record update time.'
204
- },
205
- {
206
- 'name': 'room_id',
207
- 'type_': 'varchar(31)',
208
- 'constraint': 'NOT NULL',
209
- 'comment': 'Chat room ID.'
210
- },
211
- {
212
- 'name': 'user_id',
213
- 'type_': 'varchar(24)',
214
- 'constraint': 'NOT NULL',
215
- 'comment': 'Chat room user ID.'
216
- },
217
- {
218
- 'name': 'name',
219
- 'type_': 'varchar(32)',
220
- 'constraint': 'CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL',
221
- 'comment': 'Chat room user name.'
222
- },
223
- {
224
- 'name': 'contact',
225
- 'type_': 'tinyint unsigned',
226
- 'constraint': 'NOT NULL',
227
- 'comment': 'Is the contact, 0 is contact, 1 is no contact.'
228
- },
229
- {
230
- 'name': 'valid',
231
- 'type_': 'tinyint unsigned',
232
- 'constraint': 'DEFAULT 1',
233
- 'comment': 'Is the valid, 0 is invalid, 1 is valid.'
234
- }
235
- ],
236
- 'primary': ['room_id', 'user_id'],
237
- 'comment': 'Chat room user contact table.'
238
- },
239
-
240
-
241
- ### 'message_receive'.
242
- {
243
- 'path': ('wechat', 'message_receive'),
244
- 'fields': [
245
- {
246
- 'name': 'create_time',
247
- 'type_': 'datetime',
248
- 'constraint': 'NOT NULL DEFAULT CURRENT_TIMESTAMP',
249
- 'comment': 'Record create time.'
250
- },
251
- {
252
- 'name': 'message_time',
253
- 'type_': 'datetime',
254
- 'constraint': 'NOT NULL',
255
- 'comment': 'Message time.'
256
- },
257
- {
258
- 'name': 'message_id',
259
- 'type_': 'bigint unsigned',
260
- 'constraint': 'NOT NULL',
261
- 'comment': 'Message UUID.'
262
- },
263
- {
264
- 'name': 'room_id',
265
- 'type_': 'varchar(31)',
266
- 'constraint': 'DEFAULT NULL',
267
- 'comment': 'Message chat room ID, null for private chat.'
268
- },
269
- {
270
- 'name': 'user_id',
271
- 'type_': 'varchar(24)',
272
- 'constraint': 'DEFAULT NULL',
273
- 'comment': 'Message sender user ID, null for system message.'
274
- },
275
- {
276
- 'name': 'type',
277
- 'type_': 'int unsigned',
278
- 'constraint': 'NOT NULL',
279
- 'comment': (
280
- 'Message type, '
281
- '1 is text message, '
282
- '3 is image message, '
283
- '34 is voice message, '
284
- '37 is new friend, '
285
- '42 is business card, '
286
- '43 is video message, '
287
- '47 is emoticon message, '
288
- '48 is position message, '
289
- '49 is file or quote or forward or share link or transfer money or real time location message, '
290
- '1000 is system message, '
291
- '1002 is recall message.'
292
- )
293
- },
294
- {
295
- 'name': 'data',
296
- 'type_': 'text',
297
- 'constraint': 'CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL',
298
- 'comment': 'Message data.'
299
- },
300
- {
301
- 'name': 'file_id',
302
- 'type_': 'mediumint unsigned',
303
- 'constraint': 'DEFAULT NULL',
304
- 'comment': 'Message file ID, from the file database.'
305
- }
306
- ],
307
- 'primary': 'message_id',
308
- 'indexes': [
309
- {
310
- 'name': 'n_message_time',
311
- 'fields': 'message_time',
312
- 'type': 'noraml',
313
- 'comment': 'Message time normal index.'
314
- },
315
- {
316
- 'name': 'n_room_id',
317
- 'fields': 'room_id',
318
- 'type': 'noraml',
319
- 'comment': 'Message chat room ID normal index.'
320
- },
321
- {
322
- 'name': 'n_user_id',
323
- 'fields': 'user_id',
324
- 'type': 'noraml',
325
- 'comment': 'Message sender user ID normal index.'
326
- }
327
- ],
328
- 'comment': 'Message receive table.'
329
- },
330
-
331
- ### 'message_send'.
332
- {
333
- 'path': ('wechat', 'message_send'),
334
- 'fields': [
335
- {
336
- 'name': 'create_time',
337
- 'type_': 'datetime',
338
- 'constraint': 'NOT NULL DEFAULT CURRENT_TIMESTAMP',
339
- 'comment': 'Record create time.'
340
- },
341
- {
342
- 'name': 'status_time',
343
- 'type_': 'datetime',
344
- 'constraint': 'NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP',
345
- 'comment': 'Send status time.'
346
- },
347
- {
348
- 'name': 'plan_time',
349
- 'type_': 'datetime',
350
- 'constraint': 'DEFAULT NULL',
351
- 'comment': 'Send plan time.'
352
- },
353
- {
354
- 'name': 'send_id',
355
- 'type_': 'int unsigned',
356
- 'constraint': 'NOT NULL AUTO_INCREMENT',
357
- 'comment': 'Send self increase ID.'
358
- },
359
- {
360
- 'name': 'status',
361
- 'type_': 'tinyint unsigned',
362
- 'constraint': 'NOT NULL',
363
- 'comment': (
364
- 'Send status, '
365
- '0 is not sent, '
366
- '1 is handling, '
367
- '2 is send success, '
368
- '3 is send fail, '
369
- '4 is send cancel.'
370
- )
371
- },
372
- {
373
- 'name': 'type',
374
- 'type_': 'tinyint unsigned',
375
- 'constraint': 'NOT NULL',
376
- 'comment': (
377
- 'Send type, '
378
- '0 is text message, '
379
- "1 is text message with '@', "
380
- '2 is file message, '
381
- '3 is image message, '
382
- '4 is emoticon message, '
383
- '5 is pat message, '
384
- '6 is public account message, '
385
- '7 is forward message.'
386
- )
387
- },
388
- {
389
- 'name': 'receive_id',
390
- 'type_': 'varchar(31)',
391
- 'constraint': 'NOT NULL',
392
- 'comment': 'Receive to user ID or chat room ID.'
393
- },
394
- {
395
- 'name': 'parameter',
396
- 'type_': 'json',
397
- 'constraint': 'NOT NULL',
398
- 'comment': (
399
- 'Send parameters, '
400
- "when parameter 'file_id' exists, then download file and convert to parameter 'path'."
401
- )
402
- }
403
- ],
404
- 'primary': 'send_id',
405
- 'indexes': [
406
- {
407
- 'name': 'n_status_time',
408
- 'fields': 'status_time',
409
- 'type': 'noraml',
410
- 'comment': 'Send status time normal index.'
411
- },
412
- {
413
- 'name': 'n_receive_id',
414
- 'fields': 'receive_id',
415
- 'type': 'noraml',
416
- 'comment': 'Receive to user ID or chat room ID normal index.'
417
- }
418
- ],
419
- 'comment': 'Message send table.'
420
- }
421
- ]
422
-
423
- ## View stats.
424
- views_stats = [
425
-
426
- ### 'stats'.
427
- {
428
- 'path': ('wechat', 'stats'),
429
- 'items': [
430
- {
431
- 'name': 'count_receive',
432
- 'select': (
433
- 'SELECT COUNT(1)\n'
434
- 'FROM `wechat`.`message_receive`'
435
- ),
436
- 'comment': 'Message receive count.'
437
- },
438
- {
439
- 'name': 'count_send',
440
- 'select': (
441
- 'SELECT COUNT(1)\n'
442
- 'FROM `wechat`.`message_send`\n'
443
- 'WHERE `status` = 2'
444
- ),
445
- 'comment': 'Message send count.'
446
- },
447
- {
448
- 'name': 'count_user',
449
- 'select': (
450
- 'SELECT COUNT(1)\n'
451
- 'FROM `wechat`.`contact_user`'
452
- ),
453
- 'comment': 'Contact user count.'
454
- },
455
- {
456
- 'name': 'count_room',
457
- 'select': (
458
- 'SELECT COUNT(1)\n'
459
- 'FROM `wechat`.`contact_room`'
460
- ),
461
- 'comment': 'Contact room count.'
462
- },
463
- {
464
- 'name': 'count_room_user',
465
- 'select': (
466
- 'SELECT COUNT(1)\n'
467
- 'FROM `wechat`.`contact_room_user`'
468
- ),
469
- 'comment': 'Contact room user count.'
470
- },
471
- {
472
- 'name': 'last_time_receive',
473
- 'select': (
474
- 'SELECT MAX(`message_time`)\n'
475
- 'FROM `wechat`.`message_receive`'
476
- ),
477
- 'comment': 'Message last receive time.'
478
- },
479
- {
480
- 'name': 'last_time_send',
481
- 'select': (
482
- 'SELECT MAX(`status_time`)\n'
483
- 'FROM `wechat`.`message_send`\n'
484
- 'WHERE `status` = 2'
485
- ),
486
- 'comment': 'Message last send time.'
487
- }
488
- ]
489
- }
490
- ]
491
-
492
- # Build.
493
-
494
- ## WeChat.
495
- self.rrdatabase_wechat.build.build(databases, tables, views_stats=views_stats)
496
-
497
- ## File.
498
- self.rrdatabase_file.file.build()
499
-
500
- # Update.
501
- self.update_contact_user()
502
- self.update_contact_room()
503
- self.update_contact_room_user()
504
-
505
-
506
- def update_contact_user(self) -> None:
507
- """
508
- Update table `contact_user`.
509
- """
510
-
511
- # Get data.
512
- contact_table = self.rwechat.rclient.get_contact_table('user')
513
-
514
- user_data = [
515
- {
516
- 'user_id': row['id'],
517
- 'name': row['name'],
518
- 'contact': 1
519
- }
520
- for row in contact_table
521
- ]
522
- user_ids = [
523
- row['id']
524
- for row in contact_table
525
- ]
526
-
527
- # Insert and update.
528
- conn = self.rrdatabase_wechat.connect()
529
-
530
- ## Insert.
531
- if contact_table != []:
532
- conn.execute_insert(
533
- ('wechat', 'contact_user'),
534
- user_data,
535
- 'update'
536
- )
537
-
538
- ## Update.
539
- if user_ids == []:
540
- sql = (
541
- 'UPDATE `wechat`.`contact_user`\n'
542
- 'SET `contact` = 0'
543
- )
544
- else:
545
- sql = (
546
- 'UPDATE `wechat`.`contact_user`\n'
547
- 'SET `contact` = 0\n'
548
- 'WHERE `user_id` NOT IN :user_ids'
549
- )
550
- conn.execute(
551
- sql,
552
- user_ids=user_ids
553
- )
554
-
555
- ## Commit.
556
- conn.commit()
557
-
558
- ## Close.
559
- conn.close()
560
-
561
-
562
- def update_contact_room(self) -> None:
563
- """
564
- Update table `contact_room`.
565
- """
566
-
567
- # Get data.
568
- contact_table = self.rwechat.rclient.get_contact_table('room')
569
-
570
- room_data = [
571
- {
572
- 'room_id': row['id'],
573
- 'name': row['name'],
574
- 'contact': 1
575
- }
576
- for row in contact_table
577
- ]
578
- room_ids = [
579
- row['id']
580
- for row in contact_table
581
- ]
582
-
583
- # Insert and update.
584
- conn = self.rrdatabase_wechat.connect()
585
-
586
- ## Insert.
587
- if contact_table != []:
588
- conn.execute_insert(
589
- ('wechat', 'contact_room'),
590
- room_data,
591
- 'update'
592
- )
593
-
594
- ## Update.
595
- if room_ids == []:
596
- sql = (
597
- 'UPDATE `wechat`.`contact_room`\n'
598
- 'SET `contact` = 0'
599
- )
600
- else:
601
- sql = (
602
- 'UPDATE `wechat`.`contact_room`\n'
603
- 'SET `contact` = 0\n'
604
- 'WHERE `room_id` NOT IN :room_ids'
605
- )
606
- conn.execute(
607
- sql,
608
- room_ids=room_ids
609
- )
610
-
611
- ## Commit.
612
- conn.commit()
613
-
614
- ## Close.
615
- conn.close()
616
-
617
-
618
- def update_contact_room_user(
619
- self,
620
- room_id: Optional[str] = None
621
- ) -> None:
622
- """
623
- Update table `contact_room_user`.
624
-
625
- Parameters
626
- ----------
627
- room_id : Chat room ID.
628
- - `None`: Update all chat room.
629
- - `str`: Update this chat room.
630
- """
631
-
632
- # Get data.
633
-
634
- ## All.
635
- if room_id is None:
636
- contact_table = self.rwechat.rclient.get_contact_table('room')
637
-
638
- ## Given.
639
- else:
640
- contact_table = [{'id': room_id}]
641
-
642
- room_user_data = [
643
- {
644
- 'room_id': row['id'],
645
- 'user_id': user_id,
646
- 'name': name,
647
- 'contact': 1
648
- }
649
- for row in contact_table
650
- for user_id, name
651
- in self.rwechat.rclient.get_room_member_dict(row['id']).items()
652
- ]
653
- room_user_ids = [
654
- '%s,%s' % (
655
- row['room_id'],
656
- row['user_id']
657
- )
658
- for row in room_user_data
659
- ]
660
-
661
- # Insert and update.
662
- conn = self.rrdatabase_wechat.connect()
663
-
664
- ## Insert.
665
- if room_user_data != []:
666
- conn.execute_insert(
667
- ('wechat', 'contact_room_user'),
668
- room_user_data,
669
- 'update'
670
- )
671
-
672
- ## Update.
673
- if room_user_ids == []:
674
- sql = (
675
- 'UPDATE `wechat`.`contact_room_user`\n'
676
- 'SET `contact` = 0'
677
- )
678
- elif room_id is None:
679
- sql = (
680
- 'UPDATE `wechat`.`contact_room_user`\n'
681
- 'SET `contact` = 0\n'
682
- "WHERE CONCAT(`room_id`, ',', `user_id`) NOT IN :room_user_ids"
683
- )
684
- else:
685
- sql = (
686
- 'UPDATE `wechat`.`contact_room_user`\n'
687
- 'SET `contact` = 0\n'
688
- 'WHERE (\n'
689
- ' `room_id` = :room_id\n'
690
- " AND CONCAT(`room_id`, ',', `user_id`) NOT IN :room_user_ids\n"
691
- ')'
692
- )
693
- conn.execute(
694
- sql,
695
- room_user_ids=room_user_ids,
696
- room_id=room_id
697
- )
698
-
699
- ## Commit.
700
- conn.commit()
701
-
702
- ## Close.
703
- conn.close()
704
-
705
-
706
- def _to_contact_user(self) -> None:
707
- """
708
- Add handler, write record to table `contact_user`.
709
- """
710
-
711
-
712
- # Define.
713
- def handler_to_contact_user(rmessage: RMessage) -> None:
714
- """
715
- Write record to table `contact_user`.
716
-
717
- Parameters
718
- ----------
719
- rmessage : `RMessage` instance.
720
- """
721
-
722
- # Add friend.
723
- if rmessage.is_new_user:
724
-
725
- ## Generate data.
726
- name = self.rwechat.rclient.get_contact_name(rmessage.user)
727
- data = {
728
- 'user_id': rmessage.user,
729
- 'name': name,
730
- 'contact': 1
731
- }
732
-
733
- ## Insert.
734
- self.rrdatabase_wechat.execute_insert(
735
- ('wechat', 'contact_user'),
736
- data,
737
- 'update'
738
- )
739
-
740
-
741
- # Add handler.
742
- self.rwechat.rreceive.add_handler(handler_to_contact_user)
743
-
744
-
745
- def _to_contact_room(self) -> None:
746
- """
747
- Add handler, write record to table `contact_room`.
748
- """
749
-
750
-
751
- # Define.
752
- def handler_to_contact_room(rmessage: RMessage) -> None:
753
- """
754
- Write record to table `contact_room`.
755
-
756
- Parameters
757
- ----------
758
- rmessage : `RMessage` instance.
759
- """
760
-
761
- # Invite.
762
- if rmessage.is_new_room:
763
-
764
- ## Generate data.
765
- name = self.rwechat.rclient.get_contact_name(rmessage.room)
766
- data = {
767
- 'room_id': rmessage.room,
768
- 'name': name,
769
- 'contact': 1
770
- }
771
-
772
- ## Insert.
773
-
774
- ### 'contact_room'.
775
- self.rrdatabase_wechat.execute_insert(
776
- ('wechat', 'contact_room'),
777
- data,
778
- 'update'
779
- )
780
-
781
- ### 'contact_room_user'.
782
- self.update_contact_room_user(rmessage.room)
783
-
784
- # Modify room name.
785
- elif rmessage.is_change_room_name:
786
-
787
- ## Generate data.
788
- _, name = rmessage.data.rsplit('“', 1)
789
- name = name[:-1]
790
- data = {
791
- 'room_id': rmessage.room,
792
- 'name': name,
793
- 'limit': 1
794
- }
795
-
796
- ## Update.
797
- self.rrdatabase_wechat.execute_update(
798
- ('wechat', 'contact_room'),
799
- data
800
- )
801
-
802
- elif (
803
-
804
- # Kick out.
805
- rmessage.is_kick_out_room
806
-
807
- # Dissolve.
808
- or rmessage.is_dissolve_room
809
- ):
810
-
811
- ## Generate data.
812
- data = {
813
- 'room_id': rmessage.room,
814
- 'contact': 0,
815
- 'limit': 1
816
- }
817
-
818
- ## Update.
819
- self.rrdatabase_wechat.execute_update(
820
- ('wechat', 'contact_room'),
821
- data
822
- )
823
-
824
-
825
- # Add handler.
826
- self.rwechat.rreceive.add_handler(handler_to_contact_room)
827
-
828
-
829
- def _to_contact_room_user(self) -> None:
830
- """
831
- Add handler, write record to table `contact_room_user`.
832
- """
833
-
834
-
835
- # Define.
836
- def handler_to_contact_room_user(rmessage: RMessage) -> None:
837
- """
838
- Write record to table `contact_room_user`.
839
-
840
- Parameters
841
- ----------
842
- rmessage : `RMessage` instance.
843
- """
844
-
845
- # Add memeber.
846
- if rmessage.is_new_room_user:
847
-
848
- ## Sleep.
849
- sleep(1)
850
-
851
- ## Insert.
852
- self.update_contact_room_user(rmessage.room)
853
-
854
-
855
- # Add handler.
856
- self.rwechat.rreceive.add_handler(handler_to_contact_room_user)
857
-
858
-
859
- def _to_message_receive(self) -> None:
860
- """
861
- Add handler, write record to table `message_receive`.
862
- """
863
-
864
-
865
- # Define.
866
- def handler_to_message_receive(rmessage: RMessage) -> None:
867
- """
868
- Write record to table `message_receive`.
869
-
870
- Parameters
871
- ----------
872
- rmessage : `RMessage` instance.
873
- """
874
-
875
- # Upload file.
876
- if rmessage.file is None:
877
- file_id = None
878
- else:
879
- file_id = self.rrdatabase_file.file.upload(
880
- rmessage.file['path'],
881
- rmessage.file['name'],
882
- 'WeChat'
883
- )
884
-
885
- # Generate data.
886
- message_time_obj = to_time(rmessage.time)
887
- message_time_str = time_to(message_time_obj)
888
- data = {
889
- 'message_time': message_time_str,
890
- 'message_id': rmessage.id,
891
- 'room_id': rmessage.room,
892
- 'user_id': rmessage.user,
893
- 'type': rmessage.type,
894
- 'data': rmessage.data,
895
- 'file_id': file_id
896
- }
897
-
898
- # Insert.
899
- self.rrdatabase_wechat.execute_insert(
900
- ('wechat', 'message_receive'),
901
- data,
902
- 'ignore'
903
- )
904
-
905
-
906
- # Add handler.
907
- self.rwechat.rreceive.add_handler(handler_to_message_receive)
908
-
909
-
910
- def _to_message_send(self) -> None:
911
- """
912
- Add handler, write record to table `message_send`.
913
- """
914
-
915
-
916
- # Define.
917
- def handler_to_message_send(rsparam: RSendParam) -> None:
918
- """
919
- Write record to table `message_send`.
920
-
921
- Parameters
922
- ----------
923
- rsparam : `RSendParams` instance.
924
- """
925
-
926
- # Break.
927
- if rsparam.send_id is not None: return
928
-
929
- # Generate data.
930
- path = rsparam.params.get('path')
931
- params = {
932
- key: value
933
- for key, value in rsparam.params.items()
934
- if key not in (
935
- 'send_type',
936
- 'receive_id',
937
- 'path'
938
- )
939
- }
940
-
941
- ## Upload file.
942
- if path is not None:
943
- file_id = self.rrdatabase_file.file.upload(
944
- path,
945
- note='WeChat'
946
- )
947
- params['file_id'] = file_id
948
-
949
- if rsparam.exc_reports == []:
950
- status = 2
951
- else:
952
- status = 3
953
- data = {
954
- 'status': status,
955
- 'type': rsparam.send_type,
956
- 'receive_id': rsparam.receive_id,
957
- 'parameter': params
958
- }
959
-
960
- # Insert.
961
- self.rrdatabase_wechat.execute_insert(
962
- ('wechat', 'message_send'),
963
- data
964
- )
965
-
966
-
967
- # Add handler.
968
- self.rwechat.rsend.add_handler(handler_to_message_send)
969
-
970
-
971
- def _download_file(
972
- self,
973
- file_id: int
974
- ) -> tuple[str, str]:
975
- """
976
- Download file by ID.
977
-
978
- Parameters
979
- ----------
980
- file_id : File ID.
981
-
982
- Returns
983
- -------
984
- File save path and file name.
985
- """
986
-
987
- # Select.
988
- file_info = self.rrdatabase_file.file.query(file_id)
989
-
990
- # Check.
991
- file_md5 = file_info['md5']
992
- rfolder = RFolder(self.rwechat.dir_file)
993
- pattern = f'^{file_md5}$'
994
- search_path = rfolder.search(pattern)
995
-
996
- # Download.
997
- if search_path is None:
998
- save_path = '%s/%s' % (
999
- self.rwechat.dir_file,
1000
- file_md5
1001
- )
1002
- save_path = self.rrdatabase_file.file.download(
1003
- file_id,
1004
- save_path
1005
- )
1006
- else:
1007
- save_path = search_path
1008
-
1009
- file_name = file_info['name']
1010
- return save_path, file_name
1011
-
1012
-
1013
- def _from_message_send(self) -> None:
1014
- """
1015
- Read record from table `message_send`, put send queue.
1016
- """
1017
-
1018
- # Get parameter.
1019
- conn = self.rrdatabase_wechat.connect()
1020
-
1021
- # Read.
1022
- where = (
1023
- '(\n'
1024
- ' `status` = 0\n'
1025
- ' AND (\n'
1026
- ' `plan_time` IS NULL\n'
1027
- ' OR `plan_time` < NOW()\n'
1028
- ' )\n'
1029
- ')'
1030
- )
1031
- result = conn.execute_select(
1032
- ('wechat', 'message_send'),
1033
- ['send_id', 'type', 'receive_id', 'parameter'],
1034
- where,
1035
- order='`plan_time` DESC, `send_id`'
1036
- )
1037
-
1038
- # Convert.
1039
- if result.empty:
1040
- return
1041
- table = result.fetch_table()
1042
-
1043
- # Update.
1044
- send_ids = [
1045
- row['send_id']
1046
- for row in table
1047
- ]
1048
- sql = (
1049
- 'UPDATE `wechat`.`message_send`\n'
1050
- 'SET `status` = 1\n'
1051
- 'WHERE `send_id` IN :send_ids'
1052
- )
1053
- conn.execute(
1054
- sql,
1055
- send_ids=send_ids
1056
- )
1057
-
1058
- # Send.
1059
- for row in table:
1060
- send_id, type_, receive_id, parameter = row.values()
1061
- parameter: dict = json_loads(parameter)
1062
-
1063
- ## Save file.
1064
- file_id = parameter.get('file_id')
1065
- if file_id is not None:
1066
- file_path, file_name = self._download_file(file_id)
1067
- parameter['path'] = file_path
1068
- parameter['file_name'] = file_name
1069
-
1070
- self.rwechat.send(
1071
- type_,
1072
- receive_id,
1073
- send_id,
1074
- **parameter
1075
- )
1076
-
1077
- # Commit.
1078
- conn.commit()
1079
-
1080
-
1081
- @wrap_thread
1082
- def _from_message_send_loop(self) -> None:
1083
- """
1084
- In the thread, loop read record from table `message_send`, put send queue.
1085
- """
1086
-
1087
-
1088
- # Define.
1089
- def handler_update_send_status(rsparam: RSendParam) -> None:
1090
- """
1091
- Update field `status` of table `message_send`.
1092
-
1093
- Parameters
1094
- ----------
1095
- rsparam : `RSendParams` instance.
1096
- """
1097
-
1098
- # Break.
1099
- if rsparam.send_id is None:
1100
- return
1101
-
1102
- # Get parameter.
1103
- if rsparam.exc_reports == []:
1104
- status = 2
1105
- else:
1106
- status = 3
1107
- data = {
1108
- 'send_id': rsparam.send_id,
1109
- 'status': status,
1110
- 'limit': 1
1111
- }
1112
-
1113
- # Update.
1114
- self.rrdatabase_wechat.execute_update(
1115
- ('wechat', 'message_send'),
1116
- data
1117
- )
1118
-
1119
-
1120
- # Add handler.
1121
- self.rwechat.rsend.add_handler(handler_update_send_status)
1122
-
1123
- # Loop.
1124
- while True:
1125
-
1126
- # Put.
1127
- self._from_message_send()
1128
-
1129
- # Wait.
1130
- sleep(1)
1131
-
1132
-
1133
- def is_valid(
1134
- self,
1135
- rmessage: RMessage
1136
- ) -> bool:
1137
- """
1138
- Judge if is valid user or chat room from database.
1139
-
1140
- Parameters
1141
- ----------
1142
- rmessage : `RMessage` instance.
1143
-
1144
- Returns
1145
- -------
1146
- Judgment result.
1147
- - `True`: Valid.
1148
- - `False`: Invalid or no record.
1149
- """
1150
-
1151
- # Judge.
1152
-
1153
- ## User.
1154
- if rmessage.room is None:
1155
- result = rmessage.rreceive.rwechat.rdatabase.rrdatabase_wechat.execute_select(
1156
- ('wechat', 'contact_user'),
1157
- ['valid'],
1158
- '`user_id` = :user_id',
1159
- limit=1,
1160
- user_id=rmessage.user
1161
- )
1162
-
1163
- ## Room.
1164
- else:
1165
- sql = (
1166
- 'SELECT (\n'
1167
- ' SELECT `valid`\n'
1168
- ' FROM `wechat`.`contact_room_user`\n'
1169
- ' WHERE `room_id` = :room_id AND `user_id` = :user_id\n'
1170
- ' LIMIT 1\n'
1171
- ') AS `valid`\n'
1172
- 'FROM (\n'
1173
- ' SELECT `valid`\n'
1174
- ' FROM `wechat`.`contact_room`\n'
1175
- ' WHERE `room_id` = :room_id\n'
1176
- ' LIMIT 1\n'
1177
- ') AS `a`\n'
1178
- 'WHERE `valid` = 1'
1179
- )
1180
- result = rmessage.rreceive.rwechat.rdatabase.rrdatabase_wechat.execute(
1181
- sql,
1182
- room_id=rmessage.room,
1183
- user_id=rmessage.user
1184
- )
1185
-
1186
- valid = result.scalar()
1187
- judge = valid == 1
1188
-
1189
- return judge