Пример #1
0
    def deleteAllNotifications(self):
        try:
            cur = self.db.cursor()
        except Exception as e:
            LOGGER.error(str(e))
            raise InternalError('Failed to get database cursor while deleting all notifications')

        try:
            cur.execute('''DELETE FROM notification_archive''')
            self.db.commit()
        except sqlite3.Error as e:
            LOGGER.error(str(e))
            raise InternalError('Failed to delete notifications')
        finally:
            cur.close()
Пример #2
0
    def aNotificationHistoryByTopicAndTime(self, topic, fromTime=None, toTime=None):
        try:
            cur = self.db.cursor()
            topic = topic.lower()

            if toTime is not None and fromTime is None:
                qry = '''SELECT time, topic, title, content, send_failed
                    FROM notification_archive
                    WHERE topic = ? and time <= ?'''
                cur.execute(qry, (topic, toTime, ))
            elif toTime is not None and fromTime is not None:
                qry = '''SELECT time, topic, title, content, send_failed
                    FROM notification_archive
                    WHERE topic = ? and time >= ? and time <= ?'''
                cur.execute(qry, (topic, fromTime, toTime, ))
            elif toTime is None and fromTime is not None:
                qry = '''SELECT time, topic, title, content, send_failed
                    FROM notification_archive
                    WHERE topic = ? and time >= ?'''
                cur.execute(qry, (topic, fromTime, ))
            else:
                raise MissingAttributeError('Missing fromTime/toTime')

            notifications = cur.fetchall()
        except sqlite3.Error as e:
            LOGGER.error(str(e))
            raise InternalError('Failed to get notifications')
        finally:
            cur.close()

        if notifications is None:
            return []
        else:
            return [rowToDict(row) for row in notifications]
Пример #3
0
    def aNotificationHistoryByTime(self, fromTime=None, toTime=None, offset=0, limit=-1):
        try:
            cur = self.db.cursor()

            if toTime is not None and fromTime is None:
                qry = '''SELECT id, time, topic, title, content, send_failed
                    FROM notification_archive
                    WHERE time <= ? LIMIT ? OFFSET ?'''
                cur.execute(qry, (toTime, limit, offset))
            elif toTime is not None and fromTime is not None:
                qry = '''SELECT id, time, topic, title, content, send_failed
                    FROM notification_archive
                    WHERE time >= ? and time <= ? ORDER BY time DESC LIMIT ? OFFSET ?'''
                cur.execute(qry, (fromTime, toTime, limit, offset))
            elif toTime is None and fromTime is not None:
                qry = '''SELECT id, time, topic, title, content, send_failed
                    FROM notification_archive
                    WHERE time >= ? ORDER BY time DESC LIMIT ? OFFSET ?'''
                cur.execute(qry, (fromTime, limit, offset))
            else:
                qry = '''SELECT id, time, topic, title, content, send_failed
                    FROM notification_archive ORDER BY time DESC LIMIT ? OFFSET ?'''
                cur.execute(qry, (limit, offset))

            notifications = cur.fetchall()
        except sqlite3.Error as e:
            LOGGER.error(str(e))
            raise InternalError('Failed to get notifications')
        finally:
            cur.close()

        if notifications is None:
            return []
        else:
            return [rowToDict(row) for row in notifications]
Пример #4
0
    def sendNotification(self, notification):
        if any(list(map(lambda k: k not in notification.keys(), ['title', 'content']))):
            raise MissingAttributeError('Required attributes: title and content')

        try:
            result = self.notificationHandler.sendNotification(notification)
        except Exception as e:
            LOGGER.error(str(e))
            self._archiveNotification(notification, failed=True)
            raise InternalError('Failed to send notification')
        else:
            self._archiveNotification(notification)
        
        if 'attachments' in notification:
            try:
                self._archiveAttachments(notification)
            except Exception as e:
                raise InternalError('Failed to archive attachments: {}'.format(str(e)))
Пример #5
0
 def wrapper(*args, **kwargs):
     try:
         result = func(*args, **kwargs)
         if isinstance(result, (dict, list)):
             return Response(json.dumps(result),
                             content_type='application/json')
         else:
             return Response(content_type='application/json')
     except Error as e:
         LOGGER.error(e)
         return Response(json.dumps(e.toDict()),
                         status=e.code,
                         content_type='application/json')
     except Exception as e:
         LOGGER.error(e)
         error = InternalError(str(e))
         return Response(json.dumps(error.toDict()),
                         status=error.code,
                         content_type='application/json')
Пример #6
0
    def _archiveAttachments(self, notification):
        dir = os.path.join(self.attachmentsDir, self.topic)
        try:
            os.makedirs(os.path.join(self.attachmentsDir, self.topic), exist_ok=True)
        except Exception as e:
            msg = 'Unable to create directory for storing attachments: {}'.format(str(e))
            LOGGER.error(msg)
            raise InternalError(msg)

        for attachment in notification['attachments']:
            if attachment.get('backup') is True:
                try:
                    fileName = self._incrementNameIfExist(dir, attachment['filename'])
                    fileData = b64decode(attachment['content'])
                    with open(os.path.join(dir, fileName), 'wb') as f:
                        f.write(fileData)
                except Exception as e:
                    msg = 'Unable to store attachment {}: {}'.format(
                            attachment['filename'], str(e))
                    LOGGER.error(msg)
                    raise InternalError(msg)
Пример #7
0
    def __getNotificationHandler(self, topic):
        try:
            cur = self.db.cursor()
            cur.execute('''
                SELECT name, settings, handler_type FROM handler JOIN handler_type ON
                    handler.handler_type = handler_type.id
                    WHERE topic = ?
            ''', (topic.lower(), ))
            handler = cur.fetchone()
        except sqlite3.Error as e:
            LOGGER.error(str(e))
            raise InternalError(str(e))
        finally:
            cur.close()

        if handler is None:
            raise NotFoundError('No such topic '+ topic.lower())

        # If no settings were specified for that handler use the global ones
        if (handler[1] is None) or (len(handler[1]) == 0):
            try:
                cur = self.db.cursor()
                cur.execute('''
                    SELECT settings FROM global_setting WHERE handler_type = ?
                ''', (handler[2], ))
                settings = cur.fetchone()
            except sqlite3.Error as e:
                LOGGER.error(str(e))
                raise InternalError(str(e))
            finally:
                cur.close()

            settings = json.loads(settings[0])
        else:
            settings = json.loads(handler[1])

        if handler[0] == 'email':
            return EmailNotificationService(settings)
        else:
            raise UnavailableError('No notification handler found for topic')
Пример #8
0
    def updateEmailSettings(self, settings):
        try:
            cur = self.db.cursor()
            cur.execute('''
                INSERT OR REPLACE INTO global_setting (handler_type, settings)
                    VALUES ((SELECT id FROM handler_type WHERE name = 'email'),
                            ?)
                ''',
                (json.dumps(settings), ))
            self.db.commit()
        except sqlite3.Error as e:
            LOGGER.error(e)
            raise InternalError(str(e))
        finally:
            cur.close()

        return settings
Пример #9
0
    def aNotificationHistory(self):
        try:
            cur = self.db.cursor()
            cur.execute('''
                SELECT time, topic, title, content FROM notification_archive
                    WHERE topic = ?
                ''', (self.topic, ))
            notifications = cur.fetchall()
        except sqlite3.Error as e:
            LOGGER.error(str(e))
            raise InternalError('Failed to get notifications')
        finally:
            cur.close()

        if notifications is None:
            return []
        else:
            return [rowToDict(row) for row in notifications]
Пример #10
0
    def getEmailSettings(self):
        try:
            cur = self.db.cursor()
            cur.execute('''
            SELECT settings FROM global_setting JOIN handler_type
                ON global_setting.handler_type = (SELECT id FROM handler_type
                                                    WHERE name = 'email')
            ''')
            settings = cur.fetchone()
        except sqlite3.Error as e:
            LOGGER.error(e)
            raise InternalError(str(e))
        finally:
            cur.close()

        if settings is None:
            return {}
        else:
            return json.loads(settings[0])
Пример #11
0
    def aEmailHandler(self, topic):
        try:
            cur = self.db.cursor()
            cur.execute(
                    'SELECT topic, settings FROM handler WHERE topic = ?',
                    (topic.lower(), ))
            handler = cur.fetchone()
        except sqlite3.Error as e:
            LOGGER.error(e)
            raise InternalError('Failed to get email handler')
        finally:
            cur.close()

        if handler is None:
            return {}
        else:
            handler = rowToDict(handler)
            handler.update(dict(settings=json.loads(handler['settings'])))
            return handler
Пример #12
0
    def addEmailHandler(self, handler):
        # Check arguments
        if set(handler.keys()).issuperset({'topic', 'settings'}) is False:
            raise MissingAttributeError('Required attributes: topic and settings')

        try:
            cur = self.db.cursor()
            cur.execute('''
                INSERT OR REPLACE INTO handler (topic, handler_type, settings)
                VALUES (?, (SELECT id FROM handler_type WHERE name = 'email'),
                        ?)
                ''',
                (handler['topic'].lower(), json.dumps(handler['settings']), ))
            self.db.commit()
        except sqlite3.Error as e:
            LOGGER.error(e)
            raise InternalError(str(e))
        finally:
            cur.close()

        return handler
Пример #13
0
    def getEmailHandlers(self):
        try:
           cur = self.db.cursor()
           cur.execute('''
            SELECT topic, settings FROM handler
                WHERE handler_type = (SELECT id FROM handler_type WHERE name = 'email')
            ''')
           handlers = cur.fetchall()
        except sqlite3.Error as e:
            LOGGER.error(e)
            raise InternalError(str(e))
        finally:
            cur.close()

        if handlers is None:
            return []
        else:
            handlers = [rowToDict(row) for row in handlers]
            for h in handlers:
                if 'settings' in h and h['settings'] is not None:
                    h.update(dict(settings=json.loads(h['settings'])))
            return handlers
Пример #14
0
    def sendNotification(self, notification):
        msg = MIMEMultipart()

        msg['Subject'] = notification['title']
        msg['From'] = self.settings['fromAddr']
        msg['To'] = COMMASPACE.join(self.settings['toAddr'])
        msg.attach(MIMEText(notification['content']))

        try:
            if 'attachments' in notification:
                if type(notification['attachments']) is list :
                    for f in notification['attachments']:
                        if not ("filename" in f and "content" in f):
                            raise BadRequestError('One of the file is missing filename or content')
                        file_cont = base64.b64decode(f["content"].encode('utf-8'))
                        file_name = f["filename"]
                        part = MIMEApplication(file_cont, name=file_name)
                        part['Content-Diposition'] = 'attachment; filename="%s"' % file_name
                        msg.attach(part)
                else:
                    raise BadRequestError('Attachments must be a list')

            s = None

            if self.settings['ssl'] and not self.settings['starttls']:
                s = smtplib.SMTP_SSL(host=self.settings['server'],
                        port=self.settings['port'], timeout=self.timeout)
            else:
                s = smtplib.SMTP(host=self.settings['server'], port=self.settings['port'],
                        timeout=self.timeout)

            if self.settings['starttls']:
                s.starttls()

            if self.settings['auth']:
                if 'user' in self.settings and 'password' in self.settings:
                    s.login(self.settings['user'], self.settings['password'])
                else:
                    raise MissingAttributeError('No user/password supplied')

            s.sendmail(self.settings['fromAddr'], self.settings['toAddr'], msg.as_string())
        except smtplib.SMTPConnectError as e:
            LOGGER.error(str(e))
            raise InternalError('Failed to connect to SMTP server')
        except smtplib.SMTPAuthenticationError as e:
            LOGGER.warning(str(e))
            raise AuthenticationError('Failed to authenticate with SMTP server')
        except smtplib.SMTPException as e:
            LOGGER.error(str(e))
            raise InternalError('Something went wrong with sending the email')
        except Error as e:
            LOGGER.warning(str(e))
            raise e
        except Exception as e:
            LOGGER.error(str(e))
            raise UnknownError('Oops, ... Something went wrong!')
        else:
            return True
        finally:
            if s is not None:
                s.quit()
Пример #15
0
def internalError(e):
    raise InternalError('Oops...Something went wrong')