ContactBridge

Log | Files | Refs | README

spam.py (5534B)


      1 from flask import request, render_template, make_response, jsonify
      2 from flask_restx import Namespace, Resource, fields
      3 
      4 from MessageTagging.spam_detector import SpamDetector
      5 from WebAPI.utils.mailer import Mailer
      6 from database.models.messages import MessageModel
      7 from database.models.spam import SpamModel
      8 from database.repository import DbRepository
      9 
     10 spam_ns = Namespace('spam', description='Spam operations')
     11 
     12 db_repository = DbRepository()
     13 spam_model = SpamModel()
     14 message_model = MessageModel()
     15 mailer = Mailer()
     16 sd = SpamDetector()
     17 
     18 spam_read_model = spam_ns.model('Spam', {
     19     'id': fields.Integer(readOnly=True, description='The message unique identifier'),
     20     'name': fields.String(required=True, description='The senders name'),
     21     'email': fields.String(required=True, description='The email address of the sender'),
     22     'subject': fields.String(required=False, description='The subject of the message'),
     23     'content': fields.String(required=True, description='The content of the message'),
     24     'timestamp': fields.String(required=True, description='The time at which the message was sent'),
     25     'relevance': fields.Float(readOnly=True, description='relevance, tries to set to low values for spam')
     26 })
     27 
     28 @spam_ns.route('/')
     29 class MessageList(Resource):
     30 
     31     @spam_ns.doc('get_messages')
     32     @spam_ns.response(400, "sort_order must be either 'ASC' or 'DESC'")
     33     @spam_ns.response(400, "Invalid sort_by field. Must be one of {sort fields}")
     34     @spam_ns.response(406, "Invalid accept header. Must be one of {valid_accept_headers}, received: {accept_header}")
     35     @spam_ns.param('query', 'search query')
     36     @spam_ns.param('sort_by', 'Field to sort the messages by')
     37     @spam_ns.param('sort_order', 'Order to sort the messages (ASC or DESC)')
     38     @spam_ns.param('page', 'The page to retrieve')
     39     @spam_ns.param('page_size', 'The number of messages to retrieve per page')
     40     @spam_ns.produces(['application/json', 'text/html'])
     41     def get(self):
     42         """Get (paginated) messages (HTML or JSON)"""
     43         args = request.args
     44         query = args.get('query', '', type=str)
     45         page = args.get('page', 1, type=int)
     46         page_size = args.get('page_size', 10, type=int)
     47         sort_by = args.get('sort_by', 'id')  # Default sort by 'id'
     48         sort_order = args.get('sort_order', 'ASC').upper()  # Default sort order 'ASC'
     49 
     50         messages, total_pages = spam_model.get_page(page, page_size, sort=sort_by, sort_order=sort_order,
     51                                                        search=query)
     52         accept_header = request.headers.get('Accept', '')
     53 
     54         if sort_order not in ['ASC', 'DESC']:
     55             spam_ns.abort(400, "sort_order must be either 'ASC' or 'DESC'")
     56 
     57         valid_sort_fields = ['id', 'name', 'email', 'subject', 'timestamp', 'relevance', 'content']
     58         if sort_by not in valid_sort_fields:
     59             spam_ns.abort(400, f"Invalid sort_by field. Must be one of {valid_sort_fields}")
     60 
     61         valid_accept_headers = ['', 'text/html', 'application/json']
     62         if accept_header not in valid_accept_headers:
     63             spam_ns.abort(406,
     64                               f"Invalid accept header. Must be one of {valid_accept_headers}, received: {accept_header}")
     65 
     66         if 'text/html' in accept_header:
     67             response = make_response(render_template('component/messages_template.html', messages=messages))
     68             response.headers['X-Total-Pages'] = total_pages
     69             response.headers['X-Current-Page'] = page
     70             return response
     71         else:
     72             response = make_response(jsonify(messages))
     73             response.headers['X-Total-Pages'] = total_pages
     74             response.headers['X-Current-Page'] = page
     75             return response
     76 
     77 
     78 @spam_ns.route('/<int:id>')
     79 @spam_ns.response(404, 'Message not found')
     80 class Message(Resource):
     81     @spam_ns.marshal_with(spam_read_model)
     82     def get(self, id):
     83         """Get a message"""
     84         message = spam_model.get(id)
     85         if message:
     86             return message, 200
     87         else:
     88             spam_ns.abort(404, "Message not found")
     89 
     90     @spam_ns.response(204, 'Message deleted')
     91     @spam_ns.response(404, 'Message not found')
     92     def delete(self, id):
     93         """Delete a message"""
     94         message = spam_model.get(id)
     95         if not message:
     96             spam_ns.abort(404, "Message not found")
     97 
     98         try:
     99             spam_model.delete(id)
    100             return make_response('', 204)
    101         except Exception as e:
    102             spam_ns.abort(500, "An internal error occurred")
    103         """Delete a message by id"""
    104 
    105 
    106 @spam_ns.response(404, 'Message not found')
    107 @spam_ns.route('/unflag/<int:id>')
    108 class MessageList(Resource):
    109     @spam_ns.response(204, 'Message unflagged')
    110     def post(self, id):
    111         """Unflag a message (moves it to inbox)"""
    112         message = spam_model.get(id)
    113 
    114         if not message:
    115             spam_ns.abort(404, 'Message not found')
    116 
    117         parameters = [
    118             message.get('name'),
    119             message.get('email'),
    120             message.get('subject'),
    121             message.get('content'),
    122             message.get('relevance')
    123         ]
    124 
    125         if message:
    126             try:
    127                 message_model.create(parameters)
    128             except Exception as e:
    129                 spam_ns.abort(500, 'An error occurred')
    130             try:
    131                 spam_model.delete(message.get('id'))
    132             except Exception as e:
    133                 message_model.delete(message.get('id'))
    134                 spam_ns.abort(500, 'An error occurred')
    135 
    136         return '', 204