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

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 1
		socket_type = s.SOCK_DGRAM if os.name in 'nt' else s.SOCK_DGRAM | s.SO_REUSEADDR
78 1
		sock = s.socket(s.AF_INET, socket_type)
79
80 1
		msg_data = '%s data' % (self.chans) if self.fwd_data else ''
81 1
		msg_and = ' and ' if (self.fwd_data and self.fwd_alarms) else ''
82 1
		msg_alarms = 'ALARM / RESET messages' if self.fwd_alarms else ''
83
84 1
		printM('Forwarding %s%s%s to %s:%s' % (msg_data, msg_and, msg_alarms, self.addr,
85
											   self.port), sender=self.sender)
86
87 1
		try:
88 1
			while self.running:
89 1
				p = self.queue.get()	# get a packet
90 1
				self.queue.task_done()	# close the queue
91
92 1
				if 'TERM' in str(p):	# shutdown if there's a TERM message on the queue
93 1
					self._exit()
94
95 1
				if 'IMGPATH' in str(p):
96 1
					continue
97
98 1
				if ('ALARM' in str(p)) or ('RESET' in str(p)):
99 1
					if self.fwd_alarms:
100
						sock.sendto(p, (self.addr, self.port))
101
					continue
102
103 1
				if "{'" in str(p):
104 1
					if (self.fwd_data) and (rs.getCHN(p) in self.chans):
105 1
						sock.sendto(p, (self.addr, self.port))
106
107 1
				if self.testing:
108 1
					TEST['c_forward'][1] = True
109
110 1
		except Exception as e:
111
			self.alive = False
112
			printE('%s' % e, sender=self.sender)
113
			if self.testing:
114
				TEST['c_forward'][1] = False
115
			sys.exit(2)
116
117