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