Package s3 :: Module s3parser
[frames] | no frames]

Source Code for Module s3.s3parser

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4     This file parses messages using functions defined in in the template's 
  5     parser.py 
  6   
  7     @copyright: 2012-2019 (c) Sahana Software Foundation 
  8     @license: MIT 
  9   
 10     Permission is hereby granted, free of charge, to any person 
 11     obtaining a copy of this software and associated documentation 
 12     files (the "Software"), to deal in the Software without 
 13     restriction, including without limitation the rights to use, 
 14     copy, modify, merge, publish, distribute, sublicense, and/or sell 
 15     copies of the Software, and to permit persons to whom the 
 16     Software is furnished to do so, subject to the following 
 17     conditions: 
 18   
 19     The above copyright notice and this permission notice shall be 
 20     included in all copies or substantial portions of the Software. 
 21   
 22     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 23     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 24     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 25     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
 26     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 27     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 28     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
 29     OTHER DEALINGS IN THE SOFTWARE. 
 30  """ 
 31   
 32  __all__ = ("S3Parsing",) 
 33   
 34  import sys 
 35   
 36  from gluon import current 
37 38 # ============================================================================= 39 -class S3Parsing(object):
40 """ 41 Core Message Parsing Framework 42 - reusable functions 43 """ 44 45 # ------------------------------------------------------------------------- 46 @staticmethod
47 - def parser(function_name, message_id, **kwargs):
48 """ 49 1st Stage Parser 50 - called by msg.parse() 51 52 Sets the appropriate Authorisation level and then calls the 53 parser function from the template 54 """ 55 56 reply = None 57 s3db = current.s3db 58 59 # Retrieve Message 60 table = s3db.msg_message 61 message = current.db(table.message_id == message_id).select(limitby=(0, 1) 62 ).first() 63 64 from_address = message.from_address 65 if "<" in from_address: 66 from_address = from_address.split("<")[1].split(">")[0] 67 email = S3Parsing.is_session_alive(from_address) 68 if email: 69 current.auth.s3_impersonate(email) 70 else: 71 (email, password) = S3Parsing.parse_login(message) 72 if email and password: 73 current.auth.login_bare(email, password) 74 expiration = current.session.auth["expiration"] 75 table = s3db.msg_session 76 table.insert(email = email, 77 expiration_time = expiration, 78 from_address = from_address) 79 reply = "Login succesful" 80 # The message may have multiple purposes 81 #return reply 82 83 # Load the Parser template for this deployment 84 template = current.deployment_settings.get_msg_parser() 85 module_name = "applications.%s.modules.templates.%s.parser" \ 86 % (current.request.application, template) 87 __import__(module_name) 88 mymodule = sys.modules[module_name] 89 S3Parser = mymodule.S3Parser() 90 91 # Pass the message to the parser 92 try: 93 fn = getattr(S3Parser, function_name) 94 except: 95 current.log.error("Parser not found: %s" % function_name) 96 return None 97 98 reply = fn(message, **kwargs) or reply 99 if not reply: 100 return None 101 102 # Send Reply 103 current.msg.send(from_address, reply)
104 105 # ------------------------------------------------------------------------- 106 @staticmethod
107 - def parse_login(message):
108 """ 109 Authenticate a login request 110 """ 111 112 if not message or not message.body: 113 return None, None 114 115 words = message.body.split(" ") 116 login = False 117 email = None 118 password = None 119 120 if "LOGIN" in [word.upper() for word in words]: 121 login = True 122 if len(words) == 2 and login: 123 password = words[1] 124 elif len(words) == 3 and login: 125 email = words[1] 126 password = words[2] 127 if login: 128 if password and not email: 129 email = message.from_address 130 return email, password 131 else: 132 return None, None
133 134 # --------------------------------------------------------------------- 135 @staticmethod
136 - def is_session_alive(from_address):
137 """ 138 Check whether there is an alive session from the same sender 139 """ 140 141 email = None 142 now = current.request.utcnow 143 stable = current.s3db.msg_session 144 query = (stable.is_expired == False) & \ 145 (stable.from_address == from_address) 146 records = current.db(query).select(stable.id, 147 stable.created_datetime, 148 stable.expiration_time, 149 stable.email, 150 ) 151 for record in records: 152 time = record.created_datetime 153 time = time - now 154 time = time.total_seconds() 155 if time < record.expiration_time: 156 email = record.email 157 break 158 else: 159 record.update_record(is_expired = True) 160 161 return email
162 163 # --------------------------------------------------------------------- 164 @staticmethod
165 - def lookup_person(address):
166 """ 167 Lookup a Person from an Email Address 168 """ 169 170 s3db = current.s3db 171 172 if "<" in address: 173 address = address.split("<")[1].split(">")[0] 174 ptable = s3db.pr_person 175 ctable = s3db.pr_contact 176 query = (ctable.value == address) & \ 177 (ctable.contact_method == "EMAIL") & \ 178 (ctable.pe_id == ptable.pe_id) & \ 179 (ptable.deleted == False) & \ 180 (ctable.deleted == False) 181 possibles = current.db(query).select(ptable.id, 182 limitby=(0, 2)) 183 if len(possibles) == 1: 184 return possibles.first().id 185 186 return None
187 188 # --------------------------------------------------------------------- 189 @staticmethod
190 - def lookup_human_resource(address):
191 """ 192 Lookup a Human Resource from an Email Address 193 """ 194 195 db = current.db 196 s3db = current.s3db 197 198 if "<" in address: 199 address = address.split("<")[1].split(">")[0] 200 hrtable = s3db.hrm_human_resource 201 ptable = db.pr_person 202 ctable = s3db.pr_contact 203 query = (ctable.value == address) & \ 204 (ctable.contact_method == "EMAIL") & \ 205 (ctable.pe_id == ptable.pe_id) & \ 206 (ptable.id == hrtable.person_id) & \ 207 (ctable.deleted == False) & \ 208 (ptable.deleted == False) & \ 209 (hrtable.deleted == False) 210 possibles = db(query).select(hrtable.id, 211 limitby=(0, 2)) 212 if len(possibles) == 1: 213 return possibles.first().id 214 215 return None
216 217 # END ========================================================================= 218