Passed
Push — master ( a5e1e1...cc3949 )
by Ian
05:51
created

build.rsudp.c_telegram.Telegrammer.__init__()   A

Complexity

Conditions 4

Size

Total Lines 38
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 4.1445

Importance

Changes 0
Metric Value
eloc 27
dl 0
loc 38
ccs 19
cts 24
cp 0.7917
rs 9.232
c 0
b 0
f 0
cc 4
nop 8
crap 4.1445

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 time
3 1
import rsudp.raspberryshake as rs
4 1
from rsudp import printM, printW, printE, helpers
5 1
from rsudp.test import TEST
6 1
import telegram as tg
7
8 1
class Telegrammer(rs.ConsumerThread):
9
	'''
10
	 .. versionadded:: 0.4.2
11
12
	.. |telegram| raw:: html
13
14
		<a href="https://t.me/" target="_blank">Telegram</a>
15
16
	.. |sasmex_use| raw:: html
17
18
		<a href="https://t.me/sasmex" target="_blank">Mexican Early Warning System (SASMEX)</a>
19
20
	|telegram| is a free messaging service which,
21
	among other things, is suited to quickly broadcasting automatic
22
	notifications via an API.
23
	It is used by the |sasmex_use| and PanamaIGC.
24
25
	:param str token: bot token from Telegram bot creation
26
	:param str chat_id: Telegram chat ID number that this module will post to
27
	:param bool send_images: whether or not to send images. if False, only alerts will be sent.
28
	:param queue.Queue q: queue of data and messages sent by :class:`rsudp.c_consumer.Consumer`
29
30
	'''
31 1
	def __init__(self, token, chat_id, testing=False,
32
				 q=False, send_images=False, extra_text=False,
33
				 sender='Telegram'):
34
		"""
35
		Initializing the Telegram message posting thread.
36
37
		"""
38 1
		super().__init__()
39 1
		self.sender = sender
40 1
		self.alive = True
41 1
		self.send_images = send_images
42 1
		self.token = token
43 1
		self.chat_id = chat_id
44 1
		self.testing = testing
45 1
		self.fmt = '%Y-%m-%d %H:%M:%S.%f'
46 1
		self.region = ' - region: %s' % rs.region.title() if rs.region else ''
47
48 1
		self._resolve_extra_text(extra_text)
49
50 1
		if q:
51 1
			self.queue = q
52
		else:
53
			printE('no queue passed to consumer! Thread will exit now!', self.sender)
54
			sys.stdout.flush()
55
			self.alive = False
56
			sys.exit()
57
58 1
		if not self.testing:
59
			self.telegram = tg.Bot(token=self.token)
60
		else:
61 1
			printW('The Telegram module will not post to Telegram in Testing mode.',
62
					self.sender, announce=False)
63
64 1
		self.livelink = u'live feed ➡️ https://stationview.raspberryshake.org/#?net=%s&sta=%s' % (rs.net, rs.stn)
65 1
		self.message0 = '(Raspberry Shake station %s.%s%s) Event detected at' % (rs.net, rs.stn, self.region)
66 1
		self.last_message = False
67
68 1
		printM('Starting.', self.sender)
69
70
71 1 View Code Duplication
	def _resolve_extra_text(self, extra_text):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
72 1
		allowable_len = 4096 - (280-103)	# length of string allowable given maximum message text & region
73 1
		if ((extra_text == '') or (extra_text == None) or (extra_text == False)):
74 1
			self.extra_text = ''
75
		else:
76
			extra_text = str(extra_text)
77
			len_ex_txt = len(extra_text)
78
79
			if len_ex_txt > allowable_len:
80
				printW('extra_text parameter is longer than allowable (%s chars) and will be truncated. Please keep extra_text at or below %s characters.' % (len_ex_txt, allowable_len), sender=self.sender)
81
				extra_text = extra_text[:allowable_len]
82
83
			self.extra_text =  ' %s' % (extra_text)
84
85
86 1
	def auth(self):
87
		if not self.testing:
88
			self.telegram = tg.Bot(token=self.token)
89
90
91 1
	def getq(self):
92 1
		d = self.queue.get()
93 1
		self.queue.task_done()
94
95 1
		if 'TERM' in str(d):
96 1
			self.alive = False
97 1
			printM('Exiting.', self.sender)
98 1
			sys.exit()
99
		else:
100 1
			return d
101
102
103 1
	def _when_alarm(self, d):
104
		'''
105
		Send a telegram in an alert scenario.
106
107
		:param bytes d: queue message
108
		'''
109 1
		event_time = helpers.fsec(helpers.get_msg_time(d))
110 1
		self.last_event_str = '%s' % (event_time.strftime(self.fmt)[:22])
111 1
		message = '%s %s UTC%s - %s' % (self.message0, self.last_event_str, self.extra_text, self.livelink)
112 1
		response = None
113 1
		try:
114 1
			printM('Sending alert...', sender=self.sender)
115 1
			printM('Telegram message: %s' % (message), sender=self.sender)
116 1
			if not self.testing:
117
				response = self.telegram.sendMessage(chat_id=self.chat_id, text=message)
118
			else:
119 1
				TEST['c_telegram'][1] = True
120
121
		except Exception as e:
122
			printE('Could not send alert - %s' % (e))
123
			try:
124
				printE('Waiting 5 seconds and trying to send again...', sender=self.sender, spaces=True)
125
				time.sleep(5)
126
				self.auth()
127
				printM('Telegram message: %s' % (message), sender=self.sender)
128
				if not self.testing:
129
					response = self.telegram.sendMessage(chat_id=self.chat_id, text=message)
130
				else:
131
					# if you are here in testing mode, there is a problem
132
					TEST['c_telegram'][1] = False
133
			except Exception as e:
134
				printE('Could not send alert - %s' % (e))
135
				response = None
136 1
		self.last_message = message
137
138
139 1
	def _when_img(self, d):
140
		'''
141
		Send a telegram image in when you get an ``IMGPATH`` message.
142
143
		:param bytes d: queue message
144
		'''
145 1
		if self.send_images:
146 1
			imgpath = helpers.get_msg_path(d)
147 1
			response = None
148 1
			if os.path.exists(imgpath):
149 1
				with open(imgpath, 'rb') as image:
150 1
					try:
151 1
						if not self.testing:
152
							printM('Uploading image to Telegram %s' % (imgpath), self.sender)
153
							response = self.telegram.sendPhoto(chat_id=self.chat_id, photo=image)
154
							printM('Sent image', sender=self.sender)
155
						else:
156 1
							printM('Image ready to send - %s' % (imgpath), self.sender)
157 1
							TEST['c_telegramimg'][1] = True
158
					except Exception as e:
159
						printE('Could not send image - %s' % (e))
160
						try:
161
							if not self.testing:
162
								printM('Waiting 5 seconds and trying to send again...', sender=self.sender)
163
								time.sleep(5.1)
164
								self.auth()
165
								printM('Uploading image to Telegram (2nd try) %s' % (imgpath), self.sender)
166
								response = self.telegram.sendPhoto(chat_id=self.chat_id, photo=image)
167
								printM('Sent image', sender=self.sender)
168
							else:
169
								# if you are here in testing mode, there is a problem
170
								TEST['c_telegramimg'][1] = False
171
						except Exception as e:
172
							printE('Could not send image - %s' % (e))
173
							response = None
174
			else:
175
				printM('Could not find image: %s' % (imgpath), sender=self.sender)
176
177
178 1 View Code Duplication
	def run(self):
179
		"""
180
		Reads data from the queue and sends a message if it sees an ALARM or IMGPATH message
181
		"""
182 1
		while True:
183 1
			d = self.getq()
184
185 1
			if 'ALARM' in str(d):
186 1
				self._when_alarm(d)
187
188 1
			elif 'IMGPATH' in str(d):
189
				self._when_img(d)
190