SipPhoneAccountCallBack   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 87
Duplicated Lines 28.74 %

Importance

Changes 0
Metric Value
dl 25
loc 87
rs 10
c 0
b 0
f 0
wmc 13

7 Methods

Rating   Name   Duplication   Size   Complexity  
B on_incoming_call() 25 44 5
A destroy() 0 3 1
A __init__() 0 12 1
A wait() 0 3 1
A __del__() 0 2 1
A answer_call() 0 5 1
A on_reg_state() 0 4 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
import logging
5
logger = logging.getLogger(__name__)
6
logger.debug("%s loaded", __name__)
7
8
import threading
9
import datetime
0 ignored issues
show
Unused Code introduced by
The import datetime seems to be unused.
Loading history...
10
import time
0 ignored issues
show
Unused Code introduced by
The import time seems to be unused.
Loading history...
11
import os
0 ignored issues
show
Unused Code introduced by
The import os seems to be unused.
Loading history...
12
import pjsua as pj
13
from doorpi import DoorPi
14
from SipPhoneCallCallBack import SipPhoneCallCallBack as CallCallback
15
16
class SipPhoneAccountCallBack(pj.AccountCallback):
17
18
    sem = None
19
20
    def __init__(self, account = None):
21
        logger.debug("__init__")
22
        pj.AccountCallback.__init__(self, account)
23
        DoorPi().event_handler.register_event('BeforeCallIncoming', __name__)
24
        DoorPi().event_handler.register_event('OnCallReconnect', __name__)
25
        DoorPi().event_handler.register_event('AfterCallReconnect', __name__)
26
        DoorPi().event_handler.register_event('OnCallBusy', __name__)
27
        DoorPi().event_handler.register_event('AfterCallBusy', __name__)
28
        DoorPi().event_handler.register_event('OnCallIncoming', __name__)
29
        DoorPi().event_handler.register_event('AfterCallIncoming', __name__)
30
        DoorPi().event_handler.register_event('OnCallReject', __name__)
31
        DoorPi().event_handler.register_event('AfterCallReject', __name__)
32
        #DoorPi().event_handler.register_event('AfterAccountRegState', __name__)
33
34
    def __del__(self):
35
        self.destroy()
36
37
    def destroy(self):
38
        logger.debug("destroy")
39
        DoorPi().event_handler.unregister_source(__name__, True)
40
41
    def wait(self):
42
        self.sem = threading.Semaphore(0)
43
        self.sem.acquire()
44
45
    def on_reg_state(self):
46
        if self.sem:
47
            if self.account.info().reg_status >= 200:
48
                self.sem.release()
49
50
        #DoorPi().event_handler('AfterAccountRegState', __name__)
51
        #logger.debug(self.account.info.reg_status)
52
53
    def answer_call(self, call):
54
        DoorPi().sipphone.current_callcallback = CallCallback()
55
        call.set_callback(DoorPi().sipphone.current_callcallback)
56
        DoorPi().sipphone.current_call = call
57
        DoorPi().sipphone.current_call.answer(code = 200)
58
59
    def on_incoming_call(self, call):
60
        # SIP-Status-Codes: http://de.wikipedia.org/wiki/SIP-Status-Codes
61
        # 200 = OK
62
        # 401 = Unauthorized
63
        # 403 = Forbidden
64
        # 486 = Busy Here
65
        # 494 = Security Agreement Required
66
        logger.debug("on_incoming_call")
67
        logger.info("Incoming call from %s", str(call.info().remote_uri))
68
        DoorPi().event_handler('BeforeCallIncoming', __name__)
69
70
        call.answer(180)
71
72
        if DoorPi().sipphone.current_call is not None and DoorPi().sipphone.current_call.is_valid():
73
            logger.debug("Incoming call while another call is active")
74
            logger.debug("- incoming.remote_uri: %s", call.info().remote_uri)
75
            logger.debug("- current.remote_uri : %s", DoorPi().sipphone.current_call.info().remote_uri)
76
77 View Code Duplication
            if call.info().remote_uri == DoorPi().sipphone.current_call.info().remote_uri:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
78
                logger.info("Current call is incoming call - quitting current and connecting to incoming. Maybe connection reset?")
79
                DoorPi().event_handler('OnCallReconnect', __name__, {'remote_uri': call.info().remote_uri})
80
                DoorPi().current_call.hangup()
81
                self.answer_call(call)
82
                DoorPi().event_handler('AfterCallReconnect', __name__)
83
                return
84
            else:
85
                logger.info("Incoming and current call are different - sending busy signal to incoming call")
86
                DoorPi().event_handler('OnCallBusy', __name__, {'remote_uri': call.info().remote_uri})
87
                call.answer(code = 494, reason = "Security Agreement Required")
88
                DoorPi().event_handler('AfterCallBusy', __name__)
89
                return
90
91 View Code Duplication
        if DoorPi().sipphone.is_admin_number(call.info().remote_uri):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
92
            logger.debug("Incoming call from trusted admin number %s -> autoanswer", call.info().remote_uri)
93
            DoorPi().event_handler('OnCallIncoming', __name__, {'remote_uri': call.info().remote_uri})
94
            self.answer_call(call)
95
            DoorPi().event_handler('AfterCallIncoming', __name__)
96
            return
97
        else:
98
            logger.debug("Incoming call ist not from a trusted admin number %s -> sending busy signal", call.info().remote_uri)
99
            DoorPi().event_handler('OnCallReject', __name__, {'remote_uri': call.info().remote_uri})
100
            call.answer(code = 494, reason = "Security Agreement Required")
101
            DoorPi().event_handler('AfterCallReject', __name__)
102
            return