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

Telegrammer._resolve_extra_text()   A

Complexity

Conditions 5

Size

Total Lines 13
Code Lines 10

Duplication

Lines 13
Ratio 100 %

Code Coverage

Tests 4
CRAP Score 10.3999

Importance

Changes 0
Metric Value
eloc 10
dl 13
loc 13
ccs 4
cts 10
cp 0.4
rs 9.3333
c 0
b 0
f 0
cc 5
nop 2
crap 10.3999
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