Passed
Push — master ( 0ed23a...45db06 )
by Ian
04:37 queued 12s
created

build.rsudp.c_telegram   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 165
Duplicated Lines 7.27 %

Importance

Changes 0
Metric Value
wmc 25
eloc 102
dl 12
loc 165
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A Telegrammer.getq() 0 10 2
A Telegrammer.__init__() 0 36 4
A Telegrammer.run() 12 12 4
B Telegrammer._when_alarm() 0 29 5
B Telegrammer._when_img() 0 32 8
A Telegrammer.auth() 0 3 2

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