ContactBridge

Log | Files | Refs | README

messages.py (5677B)


      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 messages_ns = Namespace('messages', description='Message operations')
     11 
     12 db_repository = DbRepository()
     13 message_model = MessageModel()
     14 spam_model = SpamModel()
     15 mailer = Mailer()
     16 sd = SpamDetector()
     17 
     18 message_read_model = messages_ns.model('Message', {
     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 
     29 @messages_ns.route('/')
     30 class MessageList(Resource):
     31 
     32     @messages_ns.doc('get_messages')
     33     @messages_ns.response(400, "sort_order must be either 'ASC' or 'DESC'")
     34     @messages_ns.response(400, "Invalid sort_by field. Must be one of {sort fields}")
     35     @messages_ns.response(406, "Invalid accept header. Must be one of {valid_accept_headers}, received: {accept_header}")
     36     @messages_ns.param('query', 'search query')
     37     @messages_ns.param('sort_by', 'Field to sort the messages by')
     38     @messages_ns.param('sort_order', 'Order to sort the messages (ASC or DESC)')
     39     @messages_ns.param('page', 'The page to retrieve')
     40     @messages_ns.param('page_size', 'The number of messages to retrieve per page')
     41     @messages_ns.produces(['application/json', 'text/html'])
     42     def get(self):
     43         """Get (paginated) messages (HTML or JSON)"""
     44         args = request.args
     45         query = args.get('query', '', type=str)
     46         page = args.get('page', 1, type=int)
     47         page_size = args.get('page_size', 10, type=int)
     48         sort_by = args.get('sort_by', 'id')  # Default sort by 'id'
     49         sort_order = args.get('sort_order', 'ASC').upper()  # Default sort order 'ASC'
     50 
     51         messages, total_pages = message_model.get_page(page, page_size, sort=sort_by, sort_order=sort_order,
     52                                                        search=query)
     53         accept_header = request.headers.get('Accept', '')
     54 
     55         if sort_order not in ['ASC', 'DESC']:
     56             messages_ns.abort(400, "sort_order must be either 'ASC' or 'DESC'")
     57 
     58         valid_sort_fields = ['id', 'name', 'email', 'subject', 'timestamp', 'relevance', 'content']
     59         if sort_by not in valid_sort_fields:
     60             messages_ns.abort(400, f"Invalid sort_by field. Must be one of {valid_sort_fields}")
     61 
     62         valid_accept_headers = ['', 'text/html', 'application/json']
     63         if accept_header not in valid_accept_headers:
     64             messages_ns.abort(406,
     65                               f"Invalid accept header. Must be one of {valid_accept_headers}, received: {accept_header}")
     66 
     67         if 'text/html' in accept_header:
     68             response = make_response(render_template('component/messages_template.html', messages=messages))
     69             response.headers['X-Total-Pages'] = total_pages
     70             response.headers['X-Current-Page'] = page
     71             return response
     72         else:
     73             response = make_response(jsonify(messages))
     74             response.headers['X-Total-Pages'] = total_pages
     75             response.headers['X-Current-Page'] = page
     76             return response
     77 
     78 
     79 @messages_ns.route('/<int:id>')
     80 @messages_ns.response(404, 'Message not found')
     81 class Message(Resource):
     82     @messages_ns.marshal_with(message_read_model)
     83     def get(self, id):
     84         """Get a message"""
     85         message = message_model.get(id)
     86         if message:
     87             return message, 200
     88         else:
     89             messages_ns.abort(404, "Message not found")
     90 
     91     @messages_ns.response(204, 'Message deleted')
     92     @messages_ns.response(404, 'Message not found')
     93     def delete(self, id):
     94         """Delete a message"""
     95         message = message_model.get(id)
     96         if not message:
     97             messages_ns.abort(404, "Message not found")
     98 
     99         try:
    100             message_model.delete(id)
    101             return make_response('', 204)
    102         except Exception as e:
    103             messages_ns.abort(500, "An internal error occurred")
    104         """Delete a message by id"""
    105 
    106 
    107 @messages_ns.response(404, 'Message not found')
    108 @messages_ns.route('/flag/<int:id>')
    109 class MessageList(Resource):
    110     @messages_ns.response(204, 'Message flagged')
    111     def post(self, id):
    112         """Flag a message (moves it to spam)"""
    113         message = message_model.get(id)
    114 
    115         if not message:
    116             messages_ns.abort(404, 'Message not found')
    117 
    118         parameters = [
    119             message.get('name'),
    120             message.get('email'),
    121             message.get('subject'),
    122             message.get('content'),
    123             message.get('relevance')
    124         ]
    125 
    126         if message:
    127             try:
    128                 spam_model.create(parameters)
    129             except Exception as e:
    130                 messages_ns.abort(500, 'An error occurred')
    131 
    132             try:
    133                 message_model.delete(message.get('id'))
    134             except Exception as e:
    135                 spam_model.delete(message.get('id'))
    136                 messages_ns.abort(500, 'An error occurred')
    137 
    138         return '', 204