def send_reset_code(): """ Send reset_code via SMS to the user Each reset_code expires after RESET_CODE_EXPIRATION If not yet set, or if expired, reset reset_code and reset_code_expires """ try: data = json.loads(request.data) if not 'phonenumber' in data: raise APIexception(code=1) phonenumber = data['phonenumber'] c = cleaner.find_one(phonenumber=phonenumber) if not c: raise APIexception(code=2) if ('reset_code' in c and 'reset_code_expires' in c and (datetime.now() < c['reset_code_expires'])): reset_code = c["reset_code"] else: (reset_code, reset_code_expires) = cleaner.generate_reset_code() cleaner.update(c["_id"], { "reset_code": reset_code, "reset_code_expires": reset_code_expires }) twilio_tools.send_SMS( phonenumber, str("Your password reset code is: " + reset_code)) return respond200() except Exception as e: return respond500(e)
def POST_receipt(list_id): """ Creates receipt + sends receipt to client via SMS A receipt is a snapshot of the list at time of POST When a receipt is posted, the list/receipt models do the work list.create_receipt retrieves a fully populated list and inserts the receipt @param {list_id} _id of list of which to take snapshot and save as receipt payload: Request is made with entire list object - have _cleaner as cleaner._id Returns _id of newly inserted receipt """ try: list_data = JSONencoder.load(request.data) # verify phonenumber in list_data -- need it to send link to receipt to client if not 'phonenumber' in list_data: raise APIexception(code=1) phonenumber = list_data['phonenumber'] # need to fetch cleaner for just cleaner's name in SMS message cleaner_id = list_data[ '_cleaner'] # something went wrong with request if _cleaner not in payload c = cleaner.find_one(id=cleaner_id) # create the receipt that will live forever receipt_id = List.create_receipt(list_id) # send SMS to client that has link to viewable receipt twilio_tools.send_receipt(phonenumber, c['name'], receipt_id) return dumpJSON({'_id': receipt_id}) except Exception as e: return respond500(e)
def PUT_send_list(id): """ Sends new agreement to client via SMS @param {id} _id of list to send as agreement to client payload: Request is made with entire list object - have _cleaner as cleaner._id Returns 200 response """ try: list_data = JSONencoder.load(request.data) # verify phonenumber in list_data -- need it to send link to receipt to client if not 'phonenumber' in list_data: raise APIexception(code=1) phonenumber = list_data['phonenumber'] # need to fetch cleaner for just cleaner's name in SMS message cleaner_id = list_data[ '_cleaner'] # something went wrong with request if _cleaner not in payload c = cleaner.find_one(id=cleaner_id) # send SMS to client that has link to viewable agreement twilio_tools.send_agreement(phonenumber, c['name'], id) return respond200() except Exception as e: return respond500(e)
def POST_reset_password(): try: data = json.loads(request.data) c = cleaner.find_one(phonenumber=data['phonenumber']) if not (c and 'reset_code' in c): raise APIexception(code=0) if not ((data['reset_code'] == c["reset_code"]) and (datetime.now() < c['reset_code_expires'])): raise APIexception(code=3) # if they made it this far all is good cleaner.update_password(c["_id"], data["password"], c["salt"]) login(cleaner.public(c)) return respond200() except Exception as e: return respond500(e)
def POST_login(): try: data = json.loads(request.data) if not ("phonenumber" in data and "password" in data): # client-side shouldn't have allowed post raise APIexception( code=0, message="phonenumber and password required to sign in") c = cleaner.find_one(phonenumber=data["phonenumber"]) if not c: raise APIexception(code=2) if not cleaner.password_valid(data["password"], c["salt"], c["hashed_pwd"]): raise APIexception(code=4) profile = cleaner.public(c) login(profile) return dumpJSON(profile) except Exception as e: return respond500(e)
def GET_validate_new_phonenumber(): """ Expects phonenumber and name in request arguments Validates that phonenumber is new and sends welcome message via SMS """ try: # get name from request if 'name' not in request.args: raise APIexception(code=6) name = request.args['name'] # get phonenumber from request if 'phonenumber' not in request.args: raise APIexception(code=1) phonenumber = request.args['phonenumber'] # insure phonenumber is new if cleaner.find(phonenumber=phonenumber): raise APIexception(code=5) twilio_tools.send_welcome(phonenumber, name) return respond200() except Exception as e: return respond500(e)
def build_map(): # re-initialize map map = {} # get translate data from spreadsheet as json r = requests.get(GOOGLE_API_REQUEST_URL) if not (r.status_code == 200 or r.status_code == '200'): raise APIexception( message='Error retrieving translate google spreadsheet') # parse translate data json into map form data = r.json() entry_list = data['feed']['entry'] entry = None keyname = None content = None translation_array = None translation_partition = None for i in range(len(entry_list)): # will add { keyname: translations } to map after building translations dictionary translations = {} # of form {'en': translation, 'es':translation,..} try: entry = entry_list[i] keyname = entry['title']['$t'] # content of form "en: phone, es: phonenumber abbr. in spanish" content = entry['content']['$t'] translation_array = re.split(r', *', content) for a in range(len(translation_array)): translation_partition = re.split(r': *', translation_array[a]) language = translation_partition[0] translation = translation_partition[1] translations[language] = translation except Exception as e: yellERROR('Error parsing translation map item: \n' + e.message + '\n' + str(entry)) continue map[keyname] = translations return map