Passed
Pull Request — master (#64)
by
unknown
06:49
created

build.rsudp.c_forward.Forward.__init__()   B

Complexity

Conditions 8

Size

Total Lines 30
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8.0046

Importance

Changes 0
Metric Value
eloc 24
dl 0
loc 30
ccs 23
cts 24
cp 0.9583
rs 7.3333
c 0
b 0
f 0
cc 8
nop 9
crap 8.0046

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1 1
import os, sys
2 1
import socket as s
3 1
from rsudp import printM, printW, printE
4 1
import rsudp.raspberryshake as rs
5 1
from rsudp.test import TEST
6
7 1
class Forward(rs.ConsumerThread):
8
	"""
9
	Single-destination data forwarding module. This consumer reads
10
	queue messages from the :class:`rsudp.c_consumer.Consumer`
11
	and forwards those messages to a specified address and port.
12
	Multiple of these threads can be started in order to deliver to
13
	more than one destination. (see the :ref:`datacast-forwarding`
14
	section in :doc:`settings`)
15
16
	.. versionadded:: 1.0.2
17
18
		The option to choose whether to forward either data or alarms or both
19
		(find boolean settings :code:`"fwd_data"` and :code:`"fwd_alarms"` in
20
		settings json files built by this version and later).
21
22
	:param str addr: IP address to pass UDP data to
23
	:param str port: network port to pass UDP data to (at specified address)
24
	:param bool fwd_data: whether or not to forward raw data packets
25
	:param bool fwd_alarms: whether or not to forward :code:`ALARM` and :code:`RESET` messages
26
	:param cha: channel(s) to forward. others will be ignored.
27
	:type cha: str or list
28
	:param queue.Queue q: queue of data and messages sent by :class:`rsudp.c_consumer.Consumer`
29
	"""
30
31 1
	def __init__(self, num, addr, port, fwd_data, fwd_alarms, cha, q, testing=False):
32
		"""
33
		Initializes data forwarding module.
34
		
35
		"""
36 1
		super().__init__()
37
38 1
		self.sender = 'Forward #%s (%s:%s)' % (num, addr, port)
39 1
		self.queue = q
40 1
		self.testing = testing
41 1
		self.addr = addr
42 1
		self.port = port
43 1
		self.fwd_data = fwd_data
44 1
		self.fwd_alarms = fwd_alarms
45 1
		self.chans = []
46 1
		cha = rs.chns if (cha == 'all') else cha
47 1
		cha = list(cha) if isinstance(cha, str) else cha
48 1
		l = rs.chns
49 1
		for c in l:
50 1
			n = 0
51 1
			for uch in cha:
52 1
				if (uch.upper() in c) and (c not in str(self.chans)):
53
					self.chans.append(c)
54 1
				n += 1
55 1
		if len(self.chans) < 1:
56 1
			self.chans = rs.chns
57 1
		self.running = True
58 1
		self.alive = True
59
60 1
		printM('Starting.', self.sender)
61
62
63 1
	def _exit(self):
64
		"""
65
		Exits the thread.
66
		"""
67 1
		self.alive = False
68 1
		printM('Exiting.', self.sender)
69 1
		sys.exit()
70
71
72 1
	def run(self):
73
		"""
74
		Gets and distributes queue objects to another address and port on the network.
75
		"""
76 1
		printM('Opening socket...', sender=self.sender)
77
		
78
		# Set the socket type correctly for macOS compatibility
79 1
		socket_type = s.SOCK_DGRAM
80 1
		sock = s.socket(s.AF_INET, socket_type)
81
		
82
		# Set SO_REUSEADDR option separately if not on Windows
83 1
		if os.name != 'nt':
84 1
			sock.setsockopt(s.SOL_SOCKET, s.SO_REUSEADDR, 1)
85
86 1
		msg_data = '%s data' % (self.chans) if self.fwd_data else ''
87 1
		msg_and = ' and ' if (self.fwd_data and self.fwd_alarms) else ''
88 1
		msg_alarms = 'ALARM / RESET messages' if self.fwd_alarms else ''
89
90 1
		printM('Forwarding %s%s%s to %s:%s' % (msg_data, msg_and, msg_alarms, self.addr, self.port), sender=self.sender)
91
92 1
		try:
93 1
			while self.running:
94 1
				p = self.queue.get()    # get a packet
95 1
				self.queue.task_done()  # close the queue
96
97 1
				if 'TERM' in str(p):    # shutdown if there's a TERM message on the queue
98 1
					self._exit()
99
100 1
				if 'IMGPATH' in str(p):
101 1
					continue
102
103 1
				if ('ALARM' in str(p)) or ('RESET' in str(p)):
104 1
					if self.fwd_alarms:
105
						sock.sendto(p, (self.addr, self.port))
106
					continue
107
108 1
				if "{'" in str(p):
109 1
					if (self.fwd_data) and (rs.getCHN(p) in self.chans):
110 1
						sock.sendto(p, (self.addr, self.port))
111
112 1
				if self.testing:
113 1
					TEST['c_forward'][1] = True
114
115 1
		except Exception as e:
116
			self.alive = False
117
			printE('%s' % e, sender=self.sender)
118
			if self.testing:
119
				TEST['c_forward'][1] = False
120
			sys.exit(2)
121
122