• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fiduswriter / fiduswriter / 10941406873

19 Sep 2024 12:55PM UTC coverage: 87.088% (-0.007%) from 87.095%
10941406873

Pull #1294

github

web-flow
Merge 0ca2fd0ed into b2c563a85
Pull Request #1294: remove JSONPATCH setting

6374 of 7319 relevant lines covered (87.09%)

4.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.96
fiduswriter/base/base_consumer.py
1
import json
13✔
2

3
from channels.generic.websocket import WebsocketConsumer
13✔
4
import logging
13✔
5

6
logger = logging.getLogger(__name__)
13✔
7

8

9
class BaseWebsocketConsumer(WebsocketConsumer):
13✔
10

11
    def init(self):
13✔
12
        self.id = 0
13✔
13
        self.accept()
13✔
14
        self.messages = {"server": 0, "client": 0, "last_ten": []}
13✔
15
        self.endpoint = self.scope["path"]
13✔
16
        self.user = self.scope["user"]
13✔
17
        if not self.user.is_authenticated:
13✔
18
            self.access_denied()
1✔
19
            return False
1✔
20
        logger.debug("Action:Opening Websocket")
13✔
21
        return True
13✔
22

23
    def connect(self):
13✔
24
        if not self.init():
13✔
25
            return False
1✔
26

27
        logger.debug(
13✔
28
            f"Action:Opening Websocket URL:{self.endpoint}"
29
            f" User:{self.user.id} ParticipantID:{self.id}"
30
        )
31
        response = dict()
13✔
32
        response["type"] = "welcome"
13✔
33
        self.send_message(response)
13✔
34
        return True
13✔
35

36
    def access_denied(self):
13✔
37
        self.send_message({"type": "access_denied"})
2✔
38
        self.do_close()
2✔
39
        return
2✔
40

41
    def do_close(self):
13✔
42
        self.close()
2✔
43

44
    def receive(self, text_data=None):
13✔
45
        if not text_data:
13✔
46
            return
×
47
        message = json.loads(text_data)
13✔
48
        if message["type"] == "ping":
13✔
49
            self.send_pong()
2✔
50
            return
2✔
51
        if message["type"] == "request_resend":
13✔
52
            self.resend_messages(message["from"])
×
53
            return
×
54
        if "c" not in message and "s" not in message:
13✔
55
            self.access_denied()
1✔
56
            # Message doesn't contain needed client/server info. Ignore.
57
            return
1✔
58
        logger.debug(
13✔
59
            f"Action:Message received URL:{self.endpoint} "
60
            f"User:{self.user.id} ParticipantID:{self.id} "
61
            f"Type:{message['type']} "
62
            f"S count client:{message['s']} C count client:{message['c']} "
63
            f"S count server:{self.messages['server']} "
64
            f"C count server:{self.messages['client']}"
65
        )
66

67
        if message["c"] < (self.messages["client"] + 1):
13✔
68
            # Receive a message already received at least once. Ignore.
69
            return
2✔
70
        elif message["c"] > (self.messages["client"] + 1):
13✔
71
            # Messages from the client have been lost.
72
            logger.debug(
×
73
                f"Action:Requesting resending of lost messages from client"
74
                f" URL:{self.endpoint} User:{self.user.id} "
75
                f"ParticipantID:{self.id} from:{self.messages['client']}"
76
            )
77

78
            self.send(
×
79
                {"type": "request_resend", "from": self.messages["client"]}
80
            )
81
            return
×
82
        elif message["s"] < self.messages["server"]:
13✔
83
            # Message was sent either simultaneously with message from server
84
            # or a message from the server previously sent never arrived.
85
            # Resend the messages the client missed.
86
            logger.debug(
2✔
87
                f"Action:Simultaneous.Resend messages to client. "
88
                f"URL:{self.endpoint} User:{self.user.id} "
89
                f"ParticipantID:{self.id} from:{message['s']}"
90
            )
91

92
            self.messages["client"] += 1
2✔
93
            self.resend_messages(message["s"])
2✔
94
            self.reject_message(message)
2✔
95
            return
2✔
96
        # Message order is correct. We continue processing the data.
97
        self.messages["client"] += 1
13✔
98
        if message["type"] == "subscribe":
13✔
99
            connection_count = 0
13✔
100
            if "connection" in message:
13✔
101
                connection_count = message["connection"]
2✔
102
            self.subscribe(connection_count)
13✔
103
            return
13✔
104
        self.handle_message(message)
9✔
105

106
    def handle_message(self, message):
13✔
107
        pass
×
108

109
    def reject_message(self, message):
13✔
110
        pass
×
111

112
    def subscribe(self, connection_count):
13✔
113
        self.send_message({"type": "subscribed"})
13✔
114

115
    def send_message(self, message):
13✔
116
        self.messages["server"] += 1
13✔
117
        message["c"] = self.messages["client"]
13✔
118
        message["s"] = self.messages["server"]
13✔
119
        self.messages["last_ten"].append(message)
13✔
120
        self.messages["last_ten"] = self.messages["last_ten"][-10:]
13✔
121
        logger.debug(
13✔
122
            f"Action:Sending Message. URL:{self.endpoint} User:{self.user.id} "
123
            f"ParticipantID:{self.id} Type:{message['type']} "
124
            f"S count server:{message['s']} C count server:{message['c']}"
125
        )
126
        self.send(text_data=json.dumps(message))
13✔
127

128
    def unfixable(self):
13✔
129
        pass
×
130

131
    def resend_messages(self, from_no):
13✔
132
        to_send = self.messages["server"] - from_no
2✔
133
        logger.debug(
2✔
134
            f"Action:Resending messages to User. URL:{self.endpoint} "
135
            f"User:{self.user.id} ParticipantID:{self.id} "
136
            f"number of messages to be resent:{to_send} "
137
            f"S count server:{self.messages['server']} from:{from_no}"
138
        )
139
        self.messages["server"] -= to_send
2✔
140
        if to_send > len(self.messages["last_ten"]):
2✔
141
            # Too many messages requested. We have to abort.
142
            logger.debug(
×
143
                f"Action:Lot of messages requested. URL:{self.endpoint} "
144
                f"User:{self.user.id} ParticipantID:{self.id} "
145
                f"number of messages requested:{to_send}"
146
            )
147
            self.unfixable()
×
148
            return
×
149
        for message in self.messages["last_ten"][0 - to_send :]:
2✔
150
            self.send_message(message)
2✔
151

152
    def send_pong(self):
13✔
153
        self.send(text_data='{"type": "pong"}')
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc